void foo();
class Foomatic() {
void bar();
void baz()
{
std::thread a(foo); // this compiles
std::thread b(Foomatic::bar, this); // this doesn't
std::thread c(&Foomatic::bar, this); // and this compiles
// ...
}
};
我知道成员函数指针的正确语法是&Foomatic::bar
。
但为什么Foomatic::bar
不正确?那个回归了什么?为什么&Foomatic::bar
到底是正确的呢?这对我来说似乎是违反直觉的。
这不重复。您链接的问题回答了正确的语法,而不是解释原因。
我在问这里为什么C ++如此不一致,我已经知道语法是什么了。
答案 0 :(得分:4)
C ++继承了从C函数到C函数指针的转换:在C中,您只需将函数名称赋值给函数指针,而无需获取地址。这"衰变"对函数指针的函数名称似乎有些不明智,并且在C中引起了一些混淆。
当引用成员的指针不需要向后兼容C:C时没有指向成员的指针。因此,可以选择不从成员名称到成员指针的隐式转换。由于设施可以在以后添加,如果觉得有必要但几乎没有删除,则选择没有从成员名称到指向成员的指针的隐式转换。
由于有一个合理一致的接口来获取指向函数的指针,指向成员的指针以及指向对象的指针,因此似乎不需要从成员名称到指向成员的指针进行隐式转换。没有从对象名称到指向对象的指针的隐式转换。
从语义上讲,T::member
之类的东西是对成员的引用,而不是指向成员的指针。但是,我不认为可以使用当前规范来制定此类型。可能,未来的标准定义了这种语法的一些内容。
答案 1 :(得分:0)
如果&Foomatic::Bar
是指向成员的指针函数(因为您使用地址运算符&
取得函数的地址),那么{ {1}}是成员函数,而不是指向成员的函数。
这与非成员函数完全相同:如果Foomatic::Bar
是指向(非成员)函数的指针,则&foo
是一个函数。
C ++和C都不具备作为第一类对象的功能,例如,你不能拥有一个类型/值是函数的变量---只有一个指针。
作为非成员函数的语法糖特殊情况,您可以先调用所述函数而不必首先明确它,例如foo
是foo(42)
的简写,如果{{1是指向(非成员)函数的指针。