如果我在某处定义了名称空间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'
答案 0 :(得分:11)
我建议:
foo::log::Log x; // Your logging class
::log(0.0); // Log function
一般来说,我不会写using namespace foo;
,因为如果你不打算使用foo
命名空间并且它会污染全局命名空间,那就没有意义了。
答案 1 :(得分:7)
虽然它对您没有帮助,但GCC 4.1.2中的错误不正确。 log
中的log::Log
只能引用类或命名空间名称。
如果您的代码还需要使用GCC 4.1.2进行编译,那么有两个选项:
foo::log::Log
namespace log1 = foo::log;
log1::Log logger;
答案 2 :(得分:0)
cmath
出于某种原因使用::log
从全局范围获取它,并且无法在函数和命名空间之间做出决定。
命名空间保留代码以防止confusion和pollution函数签名。
Here是proper 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;
}