C ++在名称空间中声明与全局名称空间

时间:2017-01-16 23:41:16

标签: c++ scope cmath global-namespace

我对C ++中的函数声明范围有疑问。假设使用#include <cmath>将函数符号引入全局命名空间。根据我的理解,原则上它只应该在std命名空间中引入符号,但实际上,根据我自己的经验,一些符号出现在全局命名空间中。这个答案似乎证实了这一点:cmath header confusion

现在,当我在namespace foo { }内声明一个函数(与全局命名空间中的函数具有相同的原型)时会发生什么?例如,假设来自sqrt()的{​​{1}}最终在全局命名空间中,我有:

<cmath>

模板被解析为符号#include <cmath> namespace foo { template <class T> T sqrt( T x ) { // do something extra... return std::sqrt( x ); } } // ... void foo::bar() { double a = 4.0; double b = sqrt( a ); } ,它似乎应该与全局命名空间中的模板冲突。它似乎有用,但这通常是一种不好的做法吗?

更一般地说,在同一名称空间内使用时,在名称空间内声明的函数是否优先于全局函数?这是否以任何方式违反了C ++标准?

1 个答案:

答案 0 :(得分:3)

这里有两个不同的问题。

首先,拉入某些标头确实会在全局命名空间和std命名空间中注入符号。这种香肠制作与C ++的遗产和根源有关;并尝试尽可能少地在C ++中编译遗留的C代码。

其次,确实......

  

在命名空间内声明的函数优先于全局   函数,当从同一名称空间内使用时?

这是正确的。而且,不,这不是

  

以任何方式违反C ++标准?

事实上,C ++标准明确指出这是事情应该如何运作。从名称空间解析引用首先搜索相同的名称空间,作为第一个业务顺序。然后是父命名空间,如果是嵌套命名空间。然后,最终,全局命名空间。

然后,using namespace使事情复杂化。这就是为什么you should not do that

最后,为了让事情变得有趣,还有argument dependent lookup通过搜索不在当前命名空间,父命名空间或全局命名空间中的函数来将所有这些规则放在头上,但在与函数参数相同的命名空间。

没有人指责C ++是简单的。