Linux上的GCC在错误的命名空间中搜索前向声明的方法



考虑以下场景:

来源.cpp

int add(int a, int b) { return a + b; } // function in global scope

收割台.h

namespace ns
{
class A
{
public:
void do()
{
...
...
method();
...
...
}
private:
int method()
{
...
...
int add(int a, int b); // forward declaration
auto result = add(5, 10); // function call
...
...
// do something with result
}
};
}

Windows(MS编译器(上,上述操作可以正常工作。

Linux(GCC(上,它会导致链接器错误,其中方法add()被报告为未定义引用

更重要的是,该错误表明编译器试图在ns命名空间下查找add(),但它在全局命名空间中明确定义。

当链接正向声明的方法时,Linux上的GCC的行为是否与Windows上的MS编译器不同?如何解决此问题?

MS编译器的名称查找在解决将int add(int a, int b)ns::A::method的主体内声明为CCD_ 6中定义的函数的全局声明。该声明在命名空间中ns及其应该声明的函数是int ns::add(int a, int b),作为GCC(或clang(抱怨,未定义。

C++11§3.5第7段:

当没有找到具有链接的实体的块作用域声明引用其他声明时,则该实体是最里面的封闭命名空间的成员。然而,这样的声明并没有在其命名空间范围中引入成员名称。[示例:

namespace X {
void p() {
q(); // error: q not yet declared
extern void q(); // q is a member of namespace X
}
...
...
void q() { /* ... */ } // definition of X::q
}
void q() { /* ... */ } // some other, unrelated q

结束示例]

您有两种选择:-

  • int add(int a, int b)的正向声明提升到命名空间之外ns进入全局名称空间-在source.cpp中定义的名称空间

  • int add(int a, int b)的定义封装在命名空间ns:中

源.cpp

namespace ns {
int add(int a, int b) { return a + b; }
}

最新更新