c++ - 如果函数在匿名命名空间中声明,是否可以在全局命名空间中定义?
问题描述
在生产代码中,我在 .cpp 文件中找到了这个:
namespace
{
void foo(); // declared in anonymous namespace, defined below
}
void bar() // declared in corresponding .h file, defined here
{
::foo(); // call foo
}
void ::foo() // intended to refer to the anonymous foo above
{
}
我们正在使用 Visual Studio 2017。我偶然发现了这一点,因为智能感知给了我一个警告,foo
因为它找不到函数定义。但是,它编译和链接没有错误,并且代码完成了它应该做的事情。
我对它进行了测试,发现 gcc 和 clang 拒绝此代码的原因与智能感知给我警告的原因相同。
所以我的问题是:哪个编译器是正确的,为什么?
此外,出于兴趣,我向foo
全局命名空间添加了另一个声明,如下所示:
namespace
{
void foo();
}
void foo(); // another declaration
void bar()
{
::foo(); // which foo will be called?
}
void ::foo() // which foo will be defined?
{
}
现在,gcc 给了我一个错误:
错误:“void foo()”声明中的明确限定
Clang 编译它,但给了我一个警告:
警告:成员 'foo' 的额外资格 [-Wextra-qualification]
msvc 编译它就好了。
同样,哪个编译器(如果有的话)在这里是正确的?
解决方案
查看未命名命名空间上的cppreference 页面:
此定义被视为具有唯一名称的名称空间的定义和在当前范围内指定此未命名名称空间的 using 指令。
因此,“匿名”命名空间不是全局命名空间,甚至也不是未命名的。相反,它具有编译器提供的唯一名称。匿名命名空间中的函数也不::foo()
是这样。MSVC 在这里不正确。
推荐阅读
- vba - 如何将表 1 中的值添加到表 2 单元格中的值,然后在表 2 中显示结果?
- json - 为什么 JSONResult 将 Camel 大小写属性名称转换为小写?
- lua - Lua - 遍历表的问题
- opencv - NVIDIA Jetson TX2 上的 OpenCV 3 测试失败(与 gcc-7 与 gcc < 7 相关)
- android - 路径存储在数据库中现在点击播放它怎么做
- python - 如何只将一个参数传递给odeint?
- raspberry-pi - 什么都不说时GRPC获取函数调用
- python - 在下面的 CNN 模型中,reshape 在全连接层之前是如何工作的?
- javascript - 创建时无法翻转画布
- php - 如果不在同一页面中,$GET 似乎不起作用