3

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

现在,当我在 a 中声明一个函数(与全局命名空间中的函数具有相同的原型)时会发生什么namespace foo { }?例如,假设sqrt()from<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 );
}

模板被解析为 symbol double sqrt( double x ),这似乎应该与全局命名空间中的那个冲突。它似乎有效,但这通常是一种不好的做法吗?

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

4

1 回答 1

3

这里有两个不同的问题。

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

其次,是真的……

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

那是对的。而且,不,这不是

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

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

然后,using namespace让事情变得复杂。这就是为什么你不应该这样做

最后,为了让事情变得有趣,还有参数依赖查找,它通过搜索不在当前命名空间、父命名空间或全局命名空间中,而是在与函数相同的命名空间中的函数来改变所有这些规则'论据。

从来没有人指责过 C++ 简单。

于 2017-01-16T23:52:08.577 回答