名前空間 A と名前空間 B::A は共存できるか?
ちょっとした実験.
namespace A {...} namespace B { namespace A {...} ... }
のように,既に存在している名前空間 A と同じ識別子の名前空間を,別の名前空間 B の中に作ることはできるか? また,作られた場合どうやってアクセスするのか? を調べる.
最初の例:
#include <iostream> namespace base { namespace A // base::A { int hoge (10); } namespace B { namespace A // base::B::A { void print(void) { using namespace std; cout<< "hoge= "<< base::A::hoge <<endl; } } } }
base::B::A::print();
とすれば print() 関数を呼び出せる.上のコードでは base::A::hoge のように hoge にアクセスしているが,以下のようなコードはエラーとなる:
cout<< "hoge= "<< hoge <<endl; // error: 'hoge' was not declared in this scope cout<< "hoge= "<< A::hoge <<endl; // error: 'hoge' is not a member of 'base::B::A'
上のコードの,最初の A は base::A として,次の A は base::B::A としてコンパイラに認識されている. base::B::A::print において, hoge とした場合にも A::hoge とした場合にも base::B::A::hoge を意味することになるから,これらのようなエラーが発生するのだ. base::A::hoge のように正確に指定することで,最初の A の中の hoge にアクセスできる.
では,名前空間 base がなかったらどなるのか? 結論は ::A::hoge のようにアクセスすればいい.
#include <iostream> namespace A { int hoge (20); } namespace B { namespace A { void print(void) { using namespace std; cout<< "hoge= "<< ::A::hoge <<endl; } } }
以下のような指定だとエラーとなる:
cout<< "hoge= "<< hoge <<endl; // error: 'hoge' was not declared in this scope cout<< "hoge= "<< A::hoge <<endl; // error: 'hoge' is not a member of 'B::A'
base がない場合は,最初の A は無名名前空間の中に作られるので ::A としてコンパイラに認識され, B の中の A は ::B::A としてコンパイラに認識されるのである.
一番最初の例では,実は ::base::A::hoge という指定がもっとも正確だ.しかし共通の名前空間 base があるから先頭の :: を省略できたのだ.