【问题标题】:C++ Declaring function in namespace with same name as function in global namespaceC ++在命名空间中声明与全局命名空间中的函数同名的函数
【发布时间】:2017-05-31 21:44:33
【问题描述】:

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

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

#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 );
}

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

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

【问题讨论】:

    标签: c++ scope cmath global-namespace


    【解决方案1】:

    这里有两个不同的问题。

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

    其次,是真的……

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

    没错。而且,不,这不是

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

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

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

    最后,为了让事情变得有趣,还有argument dependent lookup 通过搜索不在当前命名空间、父命名空间或全局命名空间中,而是在同一个命名空间中的函数来颠覆所有这些规则作为函数的参数。

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

    【讨论】:

    • 感谢您指出依赖于参数的查找!这是我以前不知道的机制。
    猜你喜欢
    • 2013-08-16
    • 2018-07-24
    • 2012-12-18
    • 1970-01-01
    • 2019-10-29
    • 2011-03-15
    • 2013-11-19
    • 2012-11-07
    • 2019-11-15
    相关资源
    最近更新 更多