【发布时间】:2014-12-11 22:23:28
【问题描述】:
我有这个示例代码
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 指令指定指定命名空间中的名称 可以在 using 指令出现的范围内使用 使用指令。在非限定名称查找 (3.4.1) 期间,名称 看起来好像它们是在最近的封闭命名空间中声明的 其中包含 using 指令和指定的命名空间。 [注:在此上下文中,“包含”是指“直接包含或 间接”。 ]
这个奇怪的规则有什么理由吗?为什么命名空间 ns1 中的名称不能直接出现在命名空间 ns2 中?
【问题讨论】:
-
由于我从未见过以这种方式使用“使用”,所以我冒险猜测一下。它尝试将名称拉入当前命名空间,并且可能不像您打算仅拉入函数上下文那样。那么这两个函数的冲突可能是一个问题。
-
你给编译器一个选择,ns1::foo 和 ns2::foo 都在范围内。你觉得应该选哪一个?是最近的还是最远的?当编译器选择一个与函数参数同名的全局变量时,你喜欢吗?如果你说“ns1::foo 当然!”那为什么不这样写呢?
-
根据 D&E,使用指令“使名称可访问”。由于我们(可能)不知道可以访问的完整名称集,因此它更加保守,并将它们放在命名空间层次结构中的更高级(因此它们不会意外隐藏名称)。最近的封闭命名空间可能被解释为程序的公共部分;任何封闭的东西都不那么专业,任何封闭的东西都更专业,因此应该优先考虑。但我只是猜测。
标签: c++