错误“无效使用非静态成员函数”:结果取决于编译器/操作系统?

san*_*ica 0 c++ linux static-methods msys2

使用下面的 MCVE,当我classes_test.cc使用以下命令编译源代码时

\n
$ c++ --version\nc++.exe (Rev3, Built by MSYS2 project) 10.2.0\n$ c++.exe -Wall -Wunused -Wuninitialized -g -o classes_test classes_test.cc -std=c++17\n
Run Code Online (Sandbox Code Playgroud)\n

在 Windows 10 + Msys2 下(没有选项-std=c++17我得到相同的结果),我得到了预期的结果

\n
$ ./classes_test.exe\nUsing GNU G: True\nPrototype of BaseClass::get_bc() is int (BaseClass::*)()\n
Run Code Online (Sandbox Code Playgroud)\n

当我在 Ubuntu 下的 g++ 中尝试相同的操作时,出现编译错误

\n
$ c++ --version\nc++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0\n$ c++ -Wall -Wunused -Wuninitialized -g -o classes_test classes_test.cc -std=c++17\nclasses_test.cc: In function \xe2\x80\x98int main()\xe2\x80\x99:\nclasses_test.cc:63:83: error: invalid use of non-static member function \xe2\x80\x98int BaseClass::get_bc()\xe2\x80\x99\n  63  | aseClass::get_bc()" << " is " << type(BaseClass::get_bc) << endl;\n      |                                                  ^~~~~~\n
Run Code Online (Sandbox Code Playgroud)\n

如何解释这种差异?

\n

如何使代码在 Linux 和 Msys2 中一致地工作?

\n
#include <iostream>\n#include <cstdio>\n#include <vector>\n\n#include <string>\n#include <typeinfo>\n\nusing namespace std;\n\nstruct BaseClass {\n  public:\n    explicit BaseClass() : _baseClass_int(0) {};\n    explicit BaseClass(const int bci) : _baseClass_int(bci) {};\n\n    ~BaseClass() {};\n\n    int get_bc() { return _baseClass_int; }\n    void set_bc(const int bci) { _baseClass_int = bci; }\n  private:\n    int _baseClass_int;\n};\n\n#ifdef __GNUG__\n#include <cstdlib>\n#include <memory>\n#include <cxxabi.h>\n#include <string>\n#define USING_GNUG  ("True")\n\nstd::string demangle(const char* name) {\n\n    int status = -4; // some arbitrary value to eliminate the compiler warning\n\n    // enable c++11 by passing the flag -std=c++11 to g++\n    std::unique_ptr<char, void(*)(void*)> res {\n        abi::__cxa_demangle(name, NULL, NULL, &status),\n        std::free\n    };\n\n    return (status==0) ? res.get() : name ;\n}\n\n#else\n#define USING_GNUG  ("False")\n\n// does nothing if not g++\nstd::string demangle(const char* name) {\n    return name;\n}\n\n#endif\n\n\ntemplate <class T>\nstd::string type(const T& t) {\n\n    return demangle(typeid(t).name());\n}\n\nint main() {\n\n    cout << "Using GNU G: " << USING_GNUG << endl;\n    cout << "Prototype of " << "BaseClass::get_bc()" << " is " << type(BaseClass::get_bc) << endl;\n\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Hol*_*Cat 6

该代码格式不正确,但 MinGW 默认启用一些 Microsoft 风格的扩展。

编译以-fno-ms-extensions修复该问题。