使用名称空间会导致名称隐藏吗?
考虑下面的代码:
namespace C {
class X {};
}
namespace A {
class X {};
namespace B {
using namespace C;
X x;
}
}
由于using namespace
指令,我期待x
的类型是C::X
,但是VS2010和在线LLVM / Clang编译器都会将名称空间B
X
解析为A::X
使用using声明( using C::X
)更改using指令,然后按预期方式解析为C::X
该标准说明使用指令[7.3.4.2]:
using-directive指定指定名称空间中的名称可以在use-directive之后出现using-directive的作用域中使用。 在非限定名称查找(3.4.1)期间,这些名称看起来好像是在最近的包含using-directive和提名名称空间的封闭名称空间中声明的。
我读到的是, C::X
应该像在名称空间B
声明的那样出现,这有效地隐藏了A::X
标准中的哪些部分背后是使用指令和使用声明之间的不一致? 有没有办法通过using指令来隐藏外部作用域的名称?
关于使用指令的章节似乎很清楚,你看到了预期的行为:
7.3.4p2 using-directive指定指定名称空间中的名称可以在use-directive之后出现using-directive的作用域中使用。 在不合格的名称查找(3.4.1),名字看起来好像他们既包含了使用指示符和提名命名空间最近的封闭命名空间中声明。
7.3.4p3 using-directive不会将任何成员添加到它出现的声明区域。
也就是说,using-directive将命名空间的成员添加到指令的公共名称空间祖先和所使用的名称空间的查找集中,而不直接添加到使用using-directive的作用域。 这在第二个引用中明确指出:它不会将任何成员添加到using-directive的声明区域。
后来有一个例子是为了说明其他的东西,但实际上表明了这一点:
7.3.4p4 [...]另一个例子
namespace A {
int i;
}
namespace B {
int i;
int j;
namespace C {
namespace D {
using namespace A;
int j;
int k;
int a = i; // B::i hides A::i
}
最后一个例子是用来阐明传递性(并且包含更多的代码),但是一旦删除了额外的代码,它实际上就等同于您的代码。
因此,在你的情况下,使用指令似乎并不隐藏,而是隐藏起来。
链接地址: http://www.djcxy.com/p/29767.html