指向成员函数的指针 - 语法

时间:2016-12-25 20:23:59

标签: c++ pointer-to-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不正确?那个回归了什么?为什么&Foomatic::bar到底是正确的呢?这对我来说似乎是违反直觉的。

这不重复。您链接的问题回答了正确的语法,而不是解释原因。

我在问这里为什么C ++如此不一致,我已经知道语法是什么了。

2 个答案:

答案 0 :(得分:4)

C ++继承了从C函数到C函数指针的转换:在C中,您只需将函数名称赋值给函数指针,而无需获取地址。这"衰变"对函数指针的函数名称似乎有些不明智,并且在C中引起了一些混淆。

当引用成员的指针不需要向后兼容C:C时没有指向成员的指针。因此,可以选择不从成员名称到成员指针的隐式转换。由于设施可以在以后添加,如果觉得有必要但几乎没有删除,则选择没有从成员名称到指向成员的指针的隐式转换。

由于有一个合理一致的接口来获取指向函数的指针,指向成员的指针以及指向对象的指针,因此似乎不需要从成员名称到指向成员的指针进行隐式转换。没有从对象名称到指向对象的指针的隐式转换。

从语义上讲,T::member之类的东西是对成员的引用,而不是指向成员的指针。但是,我不认为可以使用当前规范来制定此类型。可能,未来的标准定义了这种语法的一些内容。

答案 1 :(得分:0)

如果&Foomatic::Bar是指向成员的指针函数(因为您使用地址运算符&取得函数的地址),那么{ {1}}是成员函数,而不是指向成员的函数。

这与非成员函数完全相同:如果Foomatic::Bar是指向(非成员)函数的指针,则&foo是一个函数。

C ++和C都不具备作为第一类对象的功能,例如,你不能拥有一个类型/值是函数的变量---只有一个指针。

作为非成员函数的语法糖特殊情况,您可以先调用所述函数而不必首先明确它,例如foofoo(42)的简写,如果{{1是指向(非成员)函数的指针。