Nesting unnamed namespaces
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 foo
s 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.
精彩评论