开发者

Nesting unnamed namespaces

开发者 https://www.devze.com 2023-03-13 08:10 出处:网络
Is there a functional difference between these two nested usages of unnamed namespaces: namespace A { namespace {

Is there a functional difference between these two nested usages of unnamed namespaces:

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

and

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

As far as I see it, both foos will get an internal unique identifier per compilation unit and can be accessed w开发者_C百科ith A::foo - but is there a subtle or not-so-subtle difference that I'm not seeing?


Exactly as you typed, there is no difference.

You can, of course, add declarations in the first level of namespace to booth examples and then it will be a difference.

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() {/*...*/}
}}}

Note that, although you programmer have no way to distinguish, for the compiler, the namespaces are distinct:

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 { }

Usefull:

  • Nested anonymous namespace?
  • http://www.codingunit.com/cplusplus-tutorial-namespaces-and-anonymous-namespaces
  • http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Funnamed_namespaces.htm
  • http://www.informit.com/articles/article.aspx?p=31783&seqNum=6
  • http://msdn.microsoft.com/en-us/library/yct4x9k5%28v=vs.80%29.aspx

EDIT:

In respect to ADL (Argument-dependent name lookup), I understand that it will be no precedence difference in overload resolution for other foo() as below:

#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;
}

Compiler will prefer the closest foo( ) unless explicitly specified. So BClass constructor calls B::foo( ) even having a using namespace A on it. To call A::foo( ) on BClass destructor, the call must be explicitly qualified.

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

Maybe it become clearer if we think in nested named namespaces and how the argument-dependent will be solved. The olny difference will be an implicit using on the unnamed ones, but it won't change the compiler preference.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号