如何解决C ++命名空间和全局函数之间的名称冲突?

时间:2010-10-06 10:17:25

标签: c++ namespaces name-conflict

如果我在某处定义了名称空间log并使其在全局范围内可访问,则会与标准double log(double)标题中的cmath冲突。实际上,大多数编译器似乎也同意它 - 大多数版本的SunCC,MSVC,GCC - 但GCC 4.1.2没有。

不幸的是,似乎无法解决歧义,因为using声明对于命名空间标识符不合法。您是否知道即使包含log::Log,我也可以在全局命名空间中编写cmath

感谢。

编辑:有人会知道C ++ 03标准对此有何看法吗?我原以为范围运算符足以消除下面代码示例中log的使用歧义。

#include <cmath>

namespace foo
{

namespace log
{

struct Log { };

} // namespace log

} // namespace foo


using namespace foo;

int main()
{
    log::Log x;

    return 0;
}

// g++ (GCC) 4.1.2 20070115 (SUSE Linux)

// log.cpp: In function `int main()':
// log.cpp:20: error: reference to `log' is ambiguous
// /usr/include/bits/mathcalls.h:110: error: candidates are: double log(double)
//     log.cpp:7: error:                 namespace foo::log { }
// log.cpp:20: error: expected `;' before `x'

4 个答案:

答案 0 :(得分:11)

我建议:

foo::log::Log x; // Your logging class
::log(0.0); // Log function

一般来说,我不会写using namespace foo;,因为如果你不打算使用foo命名空间并且它会污染全局命名空间,那就没有意义了。

见相关问题:
How do you properly use namespaces in C++?

答案 1 :(得分:7)

虽然它对您没有帮助,但GCC 4.1.2中的错误不正确。 log中的log::Log只能引用类或命名空间名称。

如果您的代码还需要使用GCC 4.1.2进行编译,那么有两个选项:

  1. 使用完全限定名称foo::log::Log
  2. 使用命名空间别名:
  3. 
        namespace log1 = foo::log;
        log1::Log logger;
    

答案 2 :(得分:0)

cmath出于某种原因使用::log从全局范围获取它,并且无法在函数和命名空间之间做出决定。

命名空间保留代码以防止confusionpollution函数签名。

Hereproper namespace用法的完整文档演示:

#include <iostream>
#include <cmath>  // Uses ::log, which would be the log() here if it were not in a namespace, see https://stackoverflow.com/questions/11892976/why-is-my-log-in-the-std-namespace

// Silently overrides std::log
//double log(double d) { return 420; }

namespace uniquename {
    using namespace std;  // So we don't have to waste space on std:: when not needed.

    double log(double d) {
        return 42;
    }

    int main() {
        cout << "Our log: " << log(4.2) << endl;
        cout << "Standard log: " << std::log(4.2);
        return 0;
    }
}

// Global wrapper for our contained code.
int main() {
    return uniquename::main();
}

输出:

Our log: 42
Standard log: 1.43508

答案 3 :(得分:0)

在 c++0x 或 c++11 中,以下应该可以工作,使用 -std=c++0x 或 -std=c++11 编译:

#include <iostream>
#include <math.h>

namespace ___ {
namespace log {

void init() {
    std::cout << "log::init()" << std::endl;
}

} // namespace log
} // namespace ___

using namespace ___;

int main() {
    log::init();
    std::cout << ::log(3.2) << std::endl;
    return 0;
}