在C++中,“using namespace”是可传递的吗?

4
惊讶地发现下面的代码可以在VC++ 2017上编译并输出“X”:
#include <string>
#include <iostream>


namespace A {
    using namespace std;
}

namespace B {
    using namespace A;
}

namespace C {
    using namespace B;
    string a;
}

int main()
{
    C::a = "X";
    std::cout << C::a;
    return 0;
}

看起来 using namespace std 从命名空间 A 经过命名空间 B 进入命名空间 C。

这是 Visual C++ 的一个 bug 吗?还是符合语言规范?

我原本以为 using namespace std 在封闭作用域结束时结束,而该作用域在命名空间 A 的定义结尾处结束。

编辑:我理解 this question 的被接受答案也回答了我的问题。但那篇文章更多地涉及匿名命名空间,而这篇文章则涉及 using 命名空间指令的传递性。所以我认为这是一个更好的例子,这个问题是有意义的。


3
我的问题与之类似但并不相同。它与匿名命名空间等内容无关,其他人搜索该问题时将找不到那个答案,就像我没有找到一样。 - Kit Fisto
1
为什么它不能正常工作呢?using namespace将所有名称导入主机命名空间,之后它们并不会消失。 - Quentin
@KitFisto 这是链接问题的一个子问题,在被接受的答案的第一句话中得到了回答。问题出在哪里? - LogicStuff
@LogicStuff:确实,那个其他问题的答案之一也回答了我的问题。但就我所看到的而言,这些问题本身是不同的。 - Kit Fisto
@KitFisto:尽管名字叫“重复”,但通常在答案匹配的情况下使用,只要问题足够相似。这是一个权衡的过程,但没有必要仅因为问题略有不同就重复回答。将“这里有一个重复”解读为“你的答案可能在这里找到”。话虽如此,我认为这些问题并不足够相似,不能算作重复。 - Lightness Races in Orbit
1个回答

2

是的:

[C++14: 7.3.4/4]: 对于未经限定的查找(3.4.1),using-directive 是可传递的:如果一个作用域包含一个指定了第二个命名空间的 using-directive,而该命名空间本身包含 using-directives,则效果就好像来自第二个命名空间的 using-directive 也出现在第一个命名空间中。 [..]

因此,编译器是正确的; 在这里使用 using namespace 实际上将名称导入到封闭的命名空间中:

[C++14: 7.3.4/2]: using-directive 指定所提名命名空间中的名称可以在 using-directive 之后出现的范围内使用。 [..]

这里的“范围”是指命名空间的范围;一个作用域的内容并不会因为遇到 } 而消失。然而,对块作用域的熟悉有时会让人感觉到这样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接