如何正确引用匿名命名空间中的函数

时间:2011-03-31 17:33:25

标签: c++ visual-c++ gcc namespaces language-lawyer

考虑这段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();
}

2 个答案:

答案 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 ++团队报告此问题。