c++11 - 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 Compiler)上,上述工作按预期工作。
在Linux (GCC)上,它会导致链接器错误,其中该方法add()
被报告为未定义的引用。
更重要的是,错误表明编译器试图add()
在命名空间下查找ns
,但它在全局命名空间中明确定义。
在链接前向声明的方法时,Linux 上的 GCC 的行为是否与 Windows 上的 MS 编译器不同?我该如何解决这个问题?
解决方案
MS 编译器的名称查找不符合 C++11 标准,将 的声明int add(int a, int b)
解析ns::A::method
为Source.cpp
. 该声明在命名空间内
,它应该声明ns
的函数是GCC(或 clang)抱怨的,没有定义。int ns::add(int a, int b)
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)
将out of namespace 的前向声明提升ns
到全局命名空间 - 它在其中定义的地方source.cpp
附上命名空间中的
int add(int a, int b)
定义ns
:
源.cpp
namespace ns {
int add(int a, int b) { return a + b; }
}
推荐阅读
- python-3.x - selenium.common.exceptions.ElementNotInteractableException:消息:元素不可交互使用 Selenium Python 将文本发送到名字字段
- java - 我的 Maven 插件在想法中总是有触摸选项
- java - 存储库中缺少 org.renjin.cran 库
- dialogflow-es - Google Dialogflow 自定义负载是否在 Telegram 中具有调用功能?
- javascript - API 端点在不等待承诺的情况下返回有什么缺点吗?
- html5-canvas - 如何调试 HTML5 canvas pixi.js 性能?
- typescript - 打字稿:类型“字符串”不能用于索引类型“{ [key: string]: any; }”
- python - 当我运行“python manage.py runserver”时,git bash 冻结
- php - 将 Woocommerce 订单号转换为 Gravity Perks 嵌套表格
- python - Django - AttributeError:'tuple'对象没有属性'get'[DRF,Stripe,Python]