GCC 编译器产生错误:成员函数的无效使用,而 CLang 编译器则不会

Bil*_*med 11 c++ gcc compiler-specific clang++

我正在使用以下程序:

\n

在main函数中,我想打印poll_timer函数的地址。

\n

该程序使用 clang 可以成功编译并运行,但使用 GCC 则不能。

\n

我在使用 GCC 时收到以下错误

\n
"709568706/source.cpp: In function \xe2\x80\x98int main()\xe2\x80\x99:\n709568706/source.cpp:28:32: error: invalid use of member function \xe2\x80\x98static void MessagePoller::poll_timer()\xe2\x80\x99 (did you forget the \xe2\x80\x98()\xe2\x80\x99 ?)\n     std::cout << (void*)m_sut->poll_timer << std::endl;\n                         ~~~~~~~^~~~~~~~~~"\n
Run Code Online (Sandbox Code Playgroud)\n
#include <iostream>\n#include <memory>\n\nclass MessagePoller\n{\n  protected:\n    static void poll_timer()\n    {\n        std::cout << "Poll timer Base called\\n";\n    }\n};\n\nclass TestMessagePoller : public MessagePoller\n{\npublic:\n    using MessagePoller::poll_timer;\n\n};\ntypedef std::shared_ptr<TestMessagePoller> TestMessagePollerPtr;\n\nint main()\n{   \n    TestMessagePollerPtr m_sut;\n    m_sut = TestMessagePollerPtr(new TestMessagePoller());\n\n    std::cout << "HERE1\\n";\n    m_sut->poll_timer();\n    std::cout << (void*)m_sut->poll_timer << std::endl;\n\n    return 0;\n    \n}\n
Run Code Online (Sandbox Code Playgroud)\n

我尝试过一件事,删除“using”语句并将 poll_timer 的访问权限更改为公共并且有效。但我想知道该程序到底发生了什么。

\n

eca*_*mur 10

是的,这是 gcc 的一个 bug;我已提交https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109958

该错误似乎首先出现在 4.8 分支中,因此如果可以的话,您可以考虑降级到 4.7.4。

解决方法是:

  • (正如您所观察到的)使用公共继承,这样您就不必使用using-declaration
  • 使用嵌套名称说明符来代替,显式命名该类:&TestMessagePoller::poll_timer
  • 相同,但带有decltype, 即:&std::remove_cvref_t<decltype(*m_sut)>::poll_timer
  • 写一个包装器:static void poll_timer() { MessagePoller::poll_timer(); }

代码有效;& 可以用于类成员访问操作(.->),其中操作数指定静态成员函数(但不是显式对象成员函数)。这里明确排除非静态成员函数。