考虑这段C ++代码:
namespace
{
void f()
{
}
class A
{
void f()
{
::f(); // VC++: error C2039: 'f' : is not a member of '`global namespace''
}
};
}
海湾合作委员会汇编这个很好。 Visual C ++ 2008无法编译吐出C2039错误。这两个编译器中的哪一个在这里是正确的?有没有办法正确引用“global” f
?
编辑:Zack建议尝试使用这两种编译器。看起来有点奇怪。
namespace
{
void f()
{
}
class A
{
void f();
};
}
void A::f()
{
::f();
}
答案 0 :(得分:9)
VC ++ 2008在这里是错误的。根据c ++ 03标准3.4.3.4:
以一元范围为前缀的名称 查找operator ::(5.1) 全球范围,在翻译单位 它在哪里使用。名称应为 在全局命名空间范围内声明或 应该是声明的名称 由于a,在全球范围内可见 using-directive(3.4.3.2)。指某东西的用途 ::允许全局名称 即使其标识符具有,也称为 被隐藏(3.3.7)。
这里的重要部分是全局命名空间中的using指令将使用scope运算符访问这些符号。
根据7.3.1.1/1,匿名命名空间等同于:
namespace *unique* { /* empty body */ }
using namespace *unique*;
namespace *unique* { namespace-body }
因此,在这两个部分之间,独立函数应该可以在全局命名空间中访问。
答案 1 :(得分:7)
正如AcademicRobot所指出的,Visual C ++是错误的。作为一种解决方法,添加一个空的未命名的命名空间块应解决该问题(我没有要测试的Visual C ++ 2008,但这适用于Visual C ++ 2010):
// empty unnamed namespace to placate compiler
namespace { }
namespace {
void f() { }
struct A {
void f() { ::f(); }
};
}
我已向Visual C ++团队报告此问题。