gpt4 book ai didi

c++ - 为什么 C+ +'s "using namespace"以这种方式工作?

转载 作者:行者123 更新时间:2023-12-03 07:34:05 25 4
gpt4 key购买 nike

所有学生都对 C++ using 指令的行为感到惊讶。考虑这个片段( Godbolt ):

namespace NA {
int foo(Zoo::Lion);
}
namespace NB {
int foo(Zoo::Lion);
namespace NC {
namespace N1 {
int foo(Zoo::Cat);
}
namespace N2 {
int test() {
using namespace N1;
using namespace NA;
return foo(Zoo::Lion());
}
}
}
}
你可能会想 test将调用 NAfoo(Zoo::Lion) ;但实际上它最终会调用 N1foo(Zoo::Cat) .
原因是 using namespace NA实际上并没有带来来自 NA 的名字进入当前范围;它将它们带入 NA 的最不常见的祖先范围和 N2 , 即 :: .和 using namespace N1不带来自 N1 的名字进入当前范围;它将它们带入 N1 的最不常见的祖先范围和 N2 , 即 NC .在这里,我画了一个漂亮的图表:
Diagram
然后正常的非限定查找“查找”树,顺序为 testN2NCNB:: ,一旦找到名称 foo 就停止在 NC .树上的 foos,在 NB:: , 无法通过查找找到,因为它们已被 foo 隐藏在 NC .
我想我对这种机制的理解足以解释它是如何工作的。我不明白的是为什么。在设计 C++ 命名空间时,为什么他们选择这种完全奇怪的机制,而不是更直接的方式,例如“名称被带入当前范围,就像使用声明一样”或“名称被带入全局范围”或“名称留在原处,在每个‘使用’的命名空间中进行单独的查找,然后合并在一起”?
为 C++ 选择这种特殊机制的考虑因素是什么?
我正在专门寻找 C++ 设计的引用资料——书籍、博客文章、WG21 论文、D&E、ARM、反射器讨论,以及任何此类性质的东西。我特别不是在寻找“基于意见”的答案;我正在寻找设计该功能时指定的真正理由。
(我读过 The Design and Evolution of C++ (1994),第 17.4 节“命名空间”,但它甚至没有提到这种古怪的机制。D&E 说:“using 指令不会将名称引入本地范围;它只是使命名空间中的名称可访问。”这是真的,但缺乏基本原理。我希望 StackOverflow 可以做得更好。)

最佳答案

引用 C++ Primer (5th Edition) 的摘录“18.2.2. 使用命名空间成员”部分

The scope of names introduced by a using directive is more complicatedthan the scope of names in using declarations. As we’ve seen, a usingdeclaration puts the name in the same scope as that of the usingdeclaration itself. It is as if the using declaration declares a local alias forthe namespace member.

A using directive does not declare local aliases. Rather, it has the effectof lifting the namespace members into the nearest scope that containsboth the namespace itself and the using directive.

This difference in scope between a using declaration and a usingdirective stems directly from how these two facilities work. In the case ofa using declaration, we are simply making name directly accessible in thelocal scope. In contrast, a using directive makes the entire contents of anamespace available In general, a namespace might include definitionsthat cannot appear in a local scope. As a consequence, a using directiveis treated as if it appeared in the nearest enclosing namespace scope.


因此,与 using 声明相比, using 指令的作用域处理的这种差异不会阻止声明相同的名称。发生此类名称冲突时,将允许使用,但任何不明确的用法都必须明确指定预期版本。

关于c++ - 为什么 C+ +'s "using namespace"以这种方式工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65365681/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com