命名空间名称必须对范围唯一。为什么?

时间:2016-01-18 22:06:50

标签: c++ c++11 namespaces

为什么名称空间名称在其范围内必须是唯一的,这似乎是显而易见的:

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以查找全局范围内的命名空间。

因此,如果编译器可以区分命名空间的使用,为什么第一个例子是个问题呢?是否存在表达式可能引用变量或命名空间的上下文?

1 个答案:

答案 0 :(得分:3)

同一范围内同名的两个不同声明是造成问题的原因。

在第二个示例中,名称空间位于外部作用域,而变量定义位于内部作用域。这给出了一种明确的方式来决定两者之间的关系。在少数情况下仍然可能可能创建歧义,但至少定义本身不会发生冲突。

在你的第一个例子中,你可以定义一种语言,允许在同一范围内使用含糊不清的定义,只要每种语言只是以一种不模糊的方式使用。然而,C ++的设计者决定避免这种情况(和IMO一样,这是正确的 - 如果有的话,C ++已经允许太多的东西使大多数人感到模棱两可,即使规则确实明确了编译器需要做什么)。 / p>

至于能够找到namespace的第二个例子,即使它是在外部范围定义的,它被变量定义遮蔽(隐藏):那是真的,但是你'只允许在任何函数之外定义命名空间,所以在using指令(你的using namespace ...)中,编译器甚至不会在函数内部查看变量定义,因为你无法在那里定义命名空间,无论如何