2016-12-25 82 views
-1
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

@Ed Heal:这不是重复的。我不问,正确的语法是什么,因为我知道它是什么,但是**为什么**是正确的语法。答案只是说明正确的语法。 – marmistrz

+3

答案是重复的。语法不正确,因为语言规范是这样说的。为什么足球比赛长达90分钟?因为这就是规则所说的。 –

+3

也许真正的问题是为什么'a(foo)'有效,当它应该是'(&foo)'? –

回答

4

C++继承了从C函数到函数指针的转换,您可以将函数名称指定给函数指针而不需要获取地址。函数指针的这种“衰减”似乎有点不明智,并且在C中引起了一些混淆。当指向成员的指针不需要向后兼容时,C:C没有指针给成员。因此,可以选择不从成员名称到成员指针的隐式转换。由于可以在稍后添加一个设施,如果感觉有必要但很难移除,则选择不会从成员名称到指向成员的隐式转换。

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

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

0

如果&Foomatic::Bar是一个指针到成员函数(因为你正在使用的地址的运营商&取函数的地址),然后Foomatic::Bar成员函数,而不是一个指针到 - 成员功能。

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

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

至于非成员函数的语法糖特殊情况下,可以调用所述功能而不必遵从它首先明确地,例如,foo(42)是短手(*foo)(42)如果foo是指向(非成员)功能。