2017-06-16 45 views
1

我观察到,当我尝试获取指向成员函数的指针时,不同的GCC版本的行为有所不同。使用不同编译器的成员函数指针

class Foo { 
public: 
    void bar() { } 
}; 

int main() { 
    void (Foo::*func1)(void) = Foo::bar; // Error with gcc 4.3.2 and gcc 7.1.0 

    return 0; 
} 

上面的代码编译细跟GCC 4.9.2(MinGW的),GCC 6.3铛4.0上的窗户。 但导致以下的错误消息与GCC 4.3.2GCC 7.1.0(在Linux):

error: invalid use of non-static member function 'void Foo::bar()' 

如果我改变了行explcitly通过像这样操作者地址请求ADRESS :

void (Foo::*func1)(void) = &Foo::bar; // Added an ampersand 

它编译没有与所有被测试的编译器错误。

请注意,可能与其他版本有相同的区别,这只是我可以测试的一个。

那么哪一个是对的?

注意:这不是this问题的副本。我知道如何解决它。我的问题是关注不同的编译器,以及它们为什么表现不同。正如我所知,这两个变体应该在语法上是正确的,但不同的编译器似乎以不同的方式处理它。

+0

[非法使用非静态成员函数C++](https:// stackoverflow。com/questions/41326376/invalid-use-of-non-static-member-function-c) – melpomene

+0

你对那个指向非静态成员函数的指针做了什么?你如何通过没有'Foo'实例的指针调用这个函数? – JimmyB

+0

@JimmyB我不使用它,因为这只是一个最小,完整和可验证的例子。我意识到在编写Qt代码的时候,你可以用指向非静态成员函数的指针创建连接。但如果我想要,我可以使用它像'Foo foo; (foo。* func1)();' – exilit

回答

4

运算符地址(即operator&)是强制性的,以形成指向成员函数的指针。

这是可选对于pointers to non-member function or static member function,因为功能到指针的隐式转换。

指向函数的指针可以用非成员函数或静态成员函数的地址初始化。由于函数到指针的隐式转换,操作符的地址是可选的。

但是function-to-pointer implicit conversion不适用于非静态成员函数。

函数类型T的左值可以隐式转换为指向该函数的prvalue指针。这不适用于非静态成员函数,因为指向非静态成员函数的左值不存在。

顺便说一句:我试着用Gcc head versionClang head version,都未能编译。

+0

所以海湾合作委员会4.9.2,海湾合作委员会6.3和铿锵4.0错了?顺便说一句。如果人们能够从标准中快速引用,那么我对此印象深刻! – exilit

+0

@exilit是的。我用Gcc和Clang头版试了一下,都没有编译。 – songyuanyao

+0

我在wandbox上试过gcc 4.9.2和gcc 6.3.0,它们都失败了。这有些令人惊讶。它可能是导致问题的编译器标志? – exilit

0

&是采取构件的地址所需:

&Foo::bar 

相反功能,可以衰减到的函数指针。