指向具有不同编译器的成员函数的指针

Pointer to member function with different compilers

我观察到当我尝试获取指向成员函数的指针时,不同的 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.3clang 4.0 在 windows 上。 但是 gcc 4.3.2gcc 7.1.0(在 linux 上)会导致以下错误消息:

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

如果我将此行更改为通过地址运算符明确请求地址,如下所示:

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

它编译所有测试的编译器都没有错误

请注意,与其他版本可能存在相同的差异,这只是我可以测试的。

那么哪一个是正确的?

注意: 这不是 问题的重复。我知道如何解决它。我的问题集中在不同的编译器以及为什么它们的行为不同。据我所知,这两种变体在语法上都应该是正确的,但不同的编译器似乎以不同的方式处理它。

& 需要获取会员地址:

&Foo::bar

与可以衰减为函数指针的函数相反。

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

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

A pointer to function can be initialized with an address of a non-member function or a static member function. Because of the function-to-pointer implicit conversion, the address-of operator is optional.

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

An lvalue of function type T can be implicitly converted to a prvalue pointer to that function. This does not apply to non-static member functions because lvalues that refer to non-static member functions do not exist.

顺便说一句:我试过 Gcc head version and Clang head version,都编译失败。