我有这个示例代码
namespace ns1
{
void foo(int)
{
}
}
namespace ns2
{
void foo()
{
}
void bar()
{
using namespace ::ns1;
foo(42); // why compiler can't just call ns1::foo?
}
}
它不会编译错误:
prog.cpp:16:9: error: too many arguments to function ‘void ns2::foo()’
我在C ++ 2003标准中找到了这个错误的原因:
using-directive指定指定名称空间中的名称 可以在using指令出现的范围内使用 使用指令。在非限定名称查找(3.4.1)期间,名称 看起来好像是在最近的封闭命名空间中声明的 它包含using-directive和指定的命名空间。 [注意:在此上下文中,“包含”表示“直接包含或 间接地”。 ]
这条奇怪的规则有理由吗?为什么命名空间ns1中的名称不能直接出现在名称空间ns2中?
答案 0 :(得分:9)
我相信这是为了减少冲突和惊喜。由using
指令引入范围的名称是可见的,但是直接包含在本地范围中的任何内容都将优先于它。
如果你真的想在没有合格身份证的情况下给你打电话,那么你可以用using
声明来宣传它:
namespace ns1 {
void foo(int) { }
}
namespace ns2 {
void foo() { }
void bar() {
using ::ns1::foo;
foo(42); // No problem; calls ::ns1::foo.
}
}
答案 1 :(得分:2)
ns1::foo
被ns2::foo
来自N3337,§3.3.10/ 1 [basic.scope.hiding]
可以通过嵌套声明性区域或派生类(10.2)中相同名称的显式声明来隐藏名称。
您引用的部分(§7.3.4/ 2 )后面会紧跟
3 using-directive 不会将任何成员添加到它出现的声明区域。 [例如:
namespace A { int i; namespace B { namespace C { int i; } using namespace A::B::C; void f1() { i = 5; // OK, C::i visible in B and hides A::i } } // more (irrelevant) stuff }
-end example]
在您的情况下, using-directive 将ns1
中的名称引入它出现的公共祖先命名空间和ns1
的名称,意味着全局命名空间。 不在ns2
内引入它们,因此ns2::foo
的声明隐藏了ns1::foo
的声明。
如果您希望找到ns1::foo
,请改用使用声明。
void bar()
{
using ::ns1::foo;
foo(42);
}