为什么名称空间名称在其范围内必须是唯一的,这似乎是显而易见的:
namespace test{}
int test = 10; //error 'int test' redeclared as different kind of symbol
但似乎编译器能够区分名称是指变量还是命名空间:
#include <iostream>
namespace test{
int x = 2;
}
int main(){
int test = 5;
using namespace test; //I was expecting an error to occur here.
std::cout << test::x << std::endl;
}
在这段代码中,编译器(g ++ 5.2.0)不会对test
的using指令或使用test
上的作用域运算符大惊小怪,尽管有一个局部变量叫test
。上下文似乎清楚地表明它引用了命名空间,因此名称查找(如果甚至发生名称查找)跳过int
变量test
以查找全局范围内的命名空间。
因此,如果编译器可以区分命名空间的使用,为什么第一个例子是个问题呢?是否存在表达式可能引用变量或命名空间的上下文?
答案 0 :(得分:3)
同一范围内同名的两个不同声明是造成问题的原因。
在第二个示例中,名称空间位于外部作用域,而变量定义位于内部作用域。这给出了一种明确的方式来决定两者之间的关系。在少数情况下仍然可能可能创建歧义,但至少定义本身不会发生冲突。
在你的第一个例子中,你可以定义一种语言,允许在同一范围内使用含糊不清的定义,只要每种语言只是以一种不模糊的方式使用。然而,C ++的设计者决定避免这种情况(和IMO一样,这是正确的 - 如果有的话,C ++已经允许太多的东西使大多数人感到模棱两可,即使规则确实明确了编译器需要做什么)。 / p>
至于能够找到namespace
的第二个例子,即使它是在外部范围定义的,它被变量定义遮蔽(隐藏):那是真的,但是你'只允许在任何函数之外定义命名空间,所以在using指令(你的using namespace ...
)中,编译器甚至不会在函数内部查看变量定义,因为你无法在那里定义命名空间,无论如何