全局与嵌套匿名命名空间标识符访问歧义 哪款编译器符合C++标准?
问题背景
如下是涉及匿名命名空间与名称查找的C++代码:
namespace { constexpr int x = 1; } namespace X { namespace { constexpr int x = 2; } } using namespace X; int main() { static_assert( ::x == 1 ); }
各编译器表现
- MSVC:编译通过,查找
::x时优先选择全局作用域下匿名命名空间定义的x(值为1),忽略X内匿名命名空间的同名定义 - GCC、Clang:编译失败,提示
::x的查找存在歧义,存在多个候选实体
标准符合性结论
GCC与Clang的处理符合C++标准要求,MSVC的实现存在不符合规范的问题
规则依据
C++标准对匿名命名空间和
using namespace指令的名称查找有明确规定:
- 匿名命名空间内的名称会被自动注入到其直接父作用域中:全局作用域下的匿名命名空间的
x被注入全局作用域,X命名空间内的匿名命名空间的x被注入X作用域using namespace X;的语义是将X作用域下的所有可见名称,添加到其所在作用域(此处为全局作用域)的名称查找候选集合中- 此时查找
::x会同时命中两个不同的x实体,二者优先级相同,属于歧义查找,标准要求编译器必须诊断该错误
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

