嵌套未命名的命名空间

时间:2011-06-15 13:32:00

标签: c++ namespaces

这两个未命名的命名空间嵌套用法之间是否存在功能差异:

namespace A { namespace {
  void foo() {/*...*/}
}}

namespace { namespace A {
  void foo() {/*...*/}
}}}

据我所知,两个foo都将获得每个编译单元的内部唯一标识符,并且可以使用A::foo访问 - 但是有一个微妙或不那么微妙的区别,我没有看到?

1 个答案:

答案 0 :(得分:7)

正如您输入的那样,没有区别。

当然,您可以在第一级命名空间中向booth示例添加声明,然后它就会有所不同。

namespace A {
  int i;         // Accessed globally in this file as "A::i".
  namespace {
    void foo() {/*...*/}
}}


namespace {
  int i;         // Accessed globally in this file simply as "i".
  namespace A {
    void foo() {/*...*/}
}}}

请注意,尽管程序员无法区分,但对于编译器,名称空间是不同的:

unnamed_namespaces.cpp:42:5: error: reference to ‘A’ is ambiguous
unnamed_namespaces.cpp:19:17: error: candidates are: namespace A { }
unnamed_namespaces.cpp:28:19: error:                 namespace <unnamed>::A { }

有用:


编辑:

关于ADL(依赖于参数的名称查找),我知道其他foo()的重载决策没有优先级差异,如下所示:

#include    <iostream>

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

namespace A {
    namespace {
        void foo() { std::cout << "A::<unnamed>::foo()" << std::endl; }

        class   AClass
        {
        public:
            AClass( )
            {   foo( ); }
        };
    }
}


namespace {
    namespace B {
        void foo() { std::cout << "B::<unnamed>::foo()" << std::endl; }

        using namespace A;

        class   BClass
        {
        public:
            BClass( )
            {   foo( ); }

            ~BClass( )
            {   A::foo( );  }
        };
    }
}

int main( )
{
    A::foo( );
    B::foo( );
    foo( );

    A::AClass   a;
    B::BClass   b;

    return  0;
}

除非明确指定,否则编译器会更喜欢最接近的foo( )。 因此BClass构造函数调用B::foo( )即使其上有using namespace A。 要在A::foo( )析构函数上调用BClass,必须明确限定调用。

A::<unnamed>::foo()
B::<unnamed>::foo()
::foo()
A::<unnamed>::foo()
B::<unnamed>::foo()
A::<unnamed>::foo()

如果我们在嵌套的命名命名空间中思考以及如何解决依赖于参数的问题,可能会更清楚。 olny差异将是未命名的隐式using,但它不会改变编译器的首选项。