C++ 标准在 7.3.1.1p1 中非常清楚地说明了这一点:
未命名的命名空间定义的行为就像它被替换为
inline(opt) namespace unique { /* empty body */ }
using namespace unique ;
namespace unique { namespace-body }
其中 inline 出现当且仅当它出现在 unnamed-namespace-definition 中时,翻译单元中所有出现的 unique 都被相同的标识符替换,并且该标识符不同于整个程序中的所有其他标识符。
因此,从上面,我们知道您的代码实际上转换为以下内容:
namespace unique1 {}
using namespace unique1;
namespace unique1 {
namespace unique2 {}
using namespace unique2;
namespace unique2 {
struct Foo
{
};
}
}
namespace unique3 {}
using namespace unique3;
namespace unique3 {
struct Foo
{
};
}
因此,由于. Foo
_ _ _ namespace unique1
Foo
using namespace unique3;
我错了。通过下面的评论更正。
然后从 7.3.4p4:
对于非限定查找 (3.4.1),using-directive 是可传递的:如果一个作用域包含一个 using-directive,该指令指定第二个命名空间,该命名空间本身包含 using-directives,效果就像来自第二个命名空间的 using-directives出现在第一。
因此,当您提到 时Foo
,它可能意味着要么 要么unique1::unique2::Foo
,unique3::Foo
这是一个错误。请注意,另一个答案说:has hidden unique name that cannot be accessed
。这是不正确的,由于使用指令可以访问它们,只是两个名称都是可见的。
但是,通过将范围解析运算符添加::
到Foo
您可以访问unique3::Foo
,原因如下:
从 3.4.3.2p2 开始:
对于命名空间 X 和名称 m,命名空间限定查找集 S(X,m) 定义如下:令 S0(X,m) 是 X 中所有 m 声明的集合和 X 的内联命名空间集 ( 7.3.1)。如果 S0(X,m) 不为空,则 S(X,m) 为 S0(X,m);否则,S(X,m) 是 S(Ni,m) 的并集,用于通过 X 中的 using 指令指定的所有命名空间 Ni 及其内联命名空间集。
强调的部分说using-directives in X
,在您的情况下表示using namespace unique1;
and using namespace unique3;
,因此命名空间限定的查找集如下所示:S(unique3::Foo)
,这意味着unique1::unique2::Foo
不包含在集合中,因此不是错误。