【发布时间】:2011-04-21 18:02:05
【问题描述】:
如果我在某处定义命名空间 log 并使其在全局范围内可访问,这将与标准 cmath 标头中的 double log(double) 冲突。实际上,大多数编译器似乎都支持它——大多数版本的 SunCC、MSVC、GCC——但 GCC 4.1.2 没有。
不幸的是,似乎没有办法解决歧义,因为using 声明对于命名空间标识符是不合法的。即使包含cmath,您知道我可以在全局命名空间中写入log::Log 的任何方法吗?
谢谢。
编辑:有人知道 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'
【问题讨论】:
-
为什么不直接写成
foo::log::Log来避免歧义呢? -
通过
<c****>版本的C 标准头文件导入的C 标识符不应该位于std命名空间中吗?是 v4.1 的实现错误(在 g++ 4.4 中此代码工作正常)还是我记得这件事错了? -
@Matteo Italia:这些标识符必须在全局命名空间中也可以访问。见stackoverflow.com/questions/1524139/…。
-
@cj:据我从这些标准引用中了解到,就标准而言,只有当您包含
<name.h>C 标头时,这些标识符才必须放在全局命名空间中,而包括<cname>应该只将它们放在std命名空间中。 -
我发现这个 bug 很烦人,我可以修补
/usr/include/bits/mathcalls.h但是文件<cmath>期望log例如在全局命名空间中(参见 gcc 的 stdlib @ 中的第 356 行987654339@,它读取using ::log;。我想知道是否可以使用所有定义的宏来纠正所有这些行为。顺便说一下,@MatteoItalia,我在 gcc 4.7 中也发现了这个,所以如果它在 4.4 中得到修复错误又回来了。
标签: c++ namespaces name-conflict