来源:http://hi.baidu.com/lovelink/item/cc6ca9e0183224accf2d4fac
ADL,参数相关查找,也称作为Koenig查找(以Andrew Koenig的名字命名,有兴趣可以看Scott Meyer的文章The Most Important C++ People...Ever),是指在编译器对无限定域的函数调用进行名字查找时,所应用的一种查找规则。


上面的函数调用,第一个f就是无限定域的函数调用,第二个则限定了在名字空间N里面,也是说使用了完全限定名。 我们首先来看一个函数所在的域的分类: 1:类域(函数作为某个类的成员函数(静态或非静态))2:名字空间域3:全局域 而Koenig查找,它的规则就是当编译器对无限定域的函数调用进行名字查找时,除了当前名字空间域以外,也会把函数参数类型所处的名字空间加入查找的范围。 Herb提供的解释(Exceptional C++, Item 31)
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.
请看下面的例程:








































我们通常都会写如上的代码,使用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); 这样的代码(使用完全限定名)。嗯,即不直观也不方便是吗?更重要的是如果我们写的是模版代码,在模版参数还没有实例化之前,我们根本就不知道参数所处的名字空间,比如:







A class describes a set of data, along with the functions that operate on that data.
一个类描述了数据的集合以及操作这些数据的函数。 Herb的类定义,称之为接口准则(Interface Principle): For a class X, all functions, including free functions, that both"Mention" XAre "supplied with" Xare logically part of X, because they form part of the interface of X.
对应类X来说,所有函数,包括自由函数,只要它们 提及X(跟X有关) 与X一起提供都在逻辑上被认为是X的一部分,因为它们是X的接口的一部分。 关于Koenig查找,我们该说的都说了吗?其实未然,之前所描述的只是Koenig查找一般可能发生的状况,当Koenig查找规则和C++原来的Ordinal Lookup(OL,顺序查找规则)混合在一起的时候,它们之间的组合所产生的状况要比之前的例子复杂的多……