2009年4月22日水曜日

C++の名前空間は完全に独立というわけではない

このブログ記事をはてなブックマークに追加

名前の自動照合規則によって指定していない名前空間の関数が呼ばれることがある。例えば、下に示すコードでは、赤字で示したfunc(x)の呼び出し時に、コンパイラはA::func()とB::func()のどちらを呼べば良いか分からずエラーになる。目的の関数を呼び出す場合、明示的にA::func(x)やB::func(x)のように書く必要がある。この問題は、Koenigの自動照合(Koenig lookup)とかADL(argument dependent lookup, argument dependent name lookup; 実引数依存の名前探索)として知られている。

namespace A { struct X; void func(X); }; namespace B { void func(A::X x) { func(x); // どの関数が呼ばれるのか? } };

何故、同じ名前空間のB::func()だけが呼ばれずに異なる名前空間のA::func()も参照されるのかって? もし、ここで外部の名前空間が呼ばれなかったら、名前空間stdを持つ標準ライブラリを使った次のコードは通らない。

std::string str("lookup"); std::cout << "Koenig " << str << std::endl;

以下のように「正しく」書く必要がある。

std::string str("lookup"); std::operator<<(std::operator<<(std::cout, "Koenig "), str).operator<<(std::endl);

誰もこんなことは望まないと思うので、名前の自動照合がある訳だ。より詳しい内容を知りたければExceptional C++の第5章を読もう。因みに、第5章以外でもC++プログラマであるならば知っておかなくてはならないことが書かれている良書だと思う。

0 コメント: