ADL,参数相关查找,也称作为Koenig查找(以Andrew Koenig的名字命名,有兴趣可以看Scott Meyer的文章The Most Important C++ People...Ever),是指在编译器对无限定域的函数调用进行名字查找时,所应用的一种查找规则。
N::f(x, y, z); // qualified
Koenig Lookup(simplified): If you supply a function argument of class type (here x, of type A::X), then to look up the correct function name the compiler considers matching names in the namespace (here A) containing the argument's type.
using namespace std;
namespace Koenig
{
class KoenigArg
{
public:
ostream& print(ostream& out) const
{
out<<member_<<endl;
}
KoenigArg(int member = 5) : member_(member){}
private:
int member_;
};
inline ostream& operator<<(ostream& out, const KoenigArg& kArg)
{
return kArg.print(out);
}
}
int main()
{
Koenig::KoenigArg karg(10);
cout<<karg;
char c;cin>>c;
return 0;
}
我们通常都会写如上的代码,使用operator<<打印对象的状态,但是ostream& operator<<(ostream& out, const KoenigArg& kArg) 的定义是处于名字空间Koenig,为什么编译器在解析main函数(全局域)里面的operator<<调用时,它能够正确定位到Koenig名字空间里面的operator<<?这是因为根据Koenig查找规则,编译器需要把参数类型KoenigArg所在的名字空间Koenig也加入对operator<<调用的名字查找范围中。
如果没有Koenig查找规则,我们就无法直接写cout<<karg;,而是需要写类似Koenig::operator<<(std::cout, karg); 这样的代码(使用完全限定名)。嗯,即不直观也不方便是吗?更重要的是如果我们写的是模版代码,在模版参数还没有实例化之前,我们根本就不知道参数所处的名字空间,比如:
{
std::cout<<value;
}
print(karg);
A class describes a set of data, along with the functions that operate on that data.
are logically part of X, because they form part of the interface of X.