指向成员函数的指针 - 语法
Pointer to member function - syntax
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
不正确呢?那个 return 是什么意思?为什么 &Foomatic::bar
是正确的?这对我来说似乎违反直觉。
这不是重复的。您链接到的问题回答了正确的语法是什么,没有解释原因。
我在问为什么C++在这里如此不一致,我已经知道语法是什么了。
如果 &Foomatic::Bar
是指向成员函数的指针(因为您正在使用地址运算符 [=11= 获取函数的 地址 ]), 那么 Foomatic::Bar
是一个 成员函数 , 而不是指向成员函数的指针。
这与非成员函数完全相同:如果 &foo
是指向(非成员)函数的指针,那么 foo
是一个函数。
C++ 和 C 都没有作为 first-class 对象的函数,例如,您不能有一个 type/value 是函数的变量 --- 只有指向它的指针。
作为非成员函数的语法糖特例,您可以调用所述函数而不必先显式地引用它,例如,foo(42)
是 (*foo)(42)
的简写形式,如果 foo
是指向(非成员)函数的指针。
C++ 从 C 继承了从函数到函数指针的转换:在 C 中,您可以将函数名称分配给函数指针,而无需获取地址。 "decay" 将函数名称改为函数指针似乎有些不明智,并且确实在 C 语言中造成了一些混乱。
当引入指向成员的指针时,不需要向后兼容 C:C 没有指向成员的指针。因此,可以选择不进行从成员名称到成员指针的隐式转换。由于设施可以在以后添加(如果感觉有必要但很难删除),因此选择不进行从成员名称到成员指针的隐式转换。
因为有一个相当一致的接口来获取函数指针、成员指针和对象指针,所以似乎不需要像那里那样从成员名称到成员指针的隐式转换不是从对象名称到对象指针的隐式转换。
从语义上讲,T::member
是对成员的引用,而不是指向成员的指针。但是,我认为不可能用当前规范来制定这种类型。未来的标准可能会为此语法定义一些东西。
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
不正确呢?那个 return 是什么意思?为什么 &Foomatic::bar
是正确的?这对我来说似乎违反直觉。
这不是重复的。您链接到的问题回答了正确的语法是什么,没有解释原因。
我在问为什么C++在这里如此不一致,我已经知道语法是什么了。
如果 &Foomatic::Bar
是指向成员函数的指针(因为您正在使用地址运算符 [=11= 获取函数的 地址 ]), 那么 Foomatic::Bar
是一个 成员函数 , 而不是指向成员函数的指针。
这与非成员函数完全相同:如果 &foo
是指向(非成员)函数的指针,那么 foo
是一个函数。
C++ 和 C 都没有作为 first-class 对象的函数,例如,您不能有一个 type/value 是函数的变量 --- 只有指向它的指针。
作为非成员函数的语法糖特例,您可以调用所述函数而不必先显式地引用它,例如,foo(42)
是 (*foo)(42)
的简写形式,如果 foo
是指向(非成员)函数的指针。
C++ 从 C 继承了从函数到函数指针的转换:在 C 中,您可以将函数名称分配给函数指针,而无需获取地址。 "decay" 将函数名称改为函数指针似乎有些不明智,并且确实在 C 语言中造成了一些混乱。
当引入指向成员的指针时,不需要向后兼容 C:C 没有指向成员的指针。因此,可以选择不进行从成员名称到成员指针的隐式转换。由于设施可以在以后添加(如果感觉有必要但很难删除),因此选择不进行从成员名称到成员指针的隐式转换。
因为有一个相当一致的接口来获取函数指针、成员指针和对象指针,所以似乎不需要像那里那样从成员名称到成员指针的隐式转换不是从对象名称到对象指针的隐式转换。
从语义上讲,T::member
是对成员的引用,而不是指向成员的指针。但是,我认为不可能用当前规范来制定这种类型。未来的标准可能会为此语法定义一些东西。