実引数依存の名前探索
From Wikipedia, the free encyclopedia
実引数依存の名前探索 (じつひきすういぞんのなまえたんさく、ADL)とは、C++において関数呼出時に与えられた引数の型に依存して、呼び出す関数を探索 (lookup)する仕組みのことである。英語ではKoenig lookup、argument dependent lookup (ADL)、argument dependent name lookupなどと呼ばれる。なお、Koenig lookupとは、この仕組みをAndrew Koenigが提案したことにちなむ。
ADLでは、探索される名前空間は実引数に依存する。A型のオブジェクトが関数呼出の際に実引数として用いられると、Aに関連する名前空間(Aが含まれる名前空間とAの基底クラスが含まれる名前空間の和集合)からその関数が探索される。 探索の後、見つかった宣言の集合の中から多重定義の解決が行われる。 以下に例を示す。
namespace SomeSpace
{
class A {};
void f(A) {}
}
int main()
{
SomeSpace::A a;
f(a); // SomeSpace::f(a);と書かずとも、SomeSpace::fが呼ばれる。
return 0;
}
標準C++ライブラリでは、ADLを主に演算子多重定義関数に対して用いている。たとえば次のプログラムはADLが無ければコンパイルできない。
#include <iostream>
#include <string>
int main()
{
std::string msg = "Hello World, where did operator<<() come from?";
std::cout << msg << std::endl;
return 0;
}
std::ostream& std::operator <<(std::ostream&, const std::string&)と宣言された関数は、ADLによって見付かる(この関数はstd名前空間の中に存在することに注目)。ところで、std::endlは関数であるが、operator <<の引数として用いられているため、std::などといった完全な修飾が必要であることに注意。
インタフェース
C++ユーザからは、ADLで見つかる名前はクラスのインタフェースの一部と扱われる。
Standard Template Library (STL)では、一部のアルゴリズム関数がswap関数を修飾無しで呼んでいる。この場合、ADLで何も見つからなければ、stdのswap関数が呼ばれるが、ADLで見つかったときはそちらが呼ばれる。例えば、ある名前空間NSにクラスFooと関数swap(Foo&, Foo&)が定義されていると、アルゴリズム関数はNS::swap(Foo&, Foo&)を使用する。ただし、この挙動はC++03では規定されておらず、必ずしもそうなるとは限らない。C++0xで規定される見込みである。