[C++再学习系列]
ADL(Koenig)查找
ADL(Koenig)查找
ADL,参数相关查找,也称作为Koenig查找(以Andrew Koenig的名字命名),是指在编译器对无限定域的函数调用进行名字查找时,所应用的一种查找规则。
首先来看一个函数所在的域的分类:
1:类域(函数作为某个类的成员函数(静态或非静态))
2:名字空间域
3:全局域
而Koenig查找,它的规则就是当编译器对无限定域的函数调用进行名字查找时,除了当前名字空间域以外,也会把函数参数类型所处的名字空间加入查找的范围。
ADL就是为了确保使用类型X的对象x时能够像使用X的成员函数一样简单(ensure that code that uses an object x of type X can use itsnonmember function interface as easily as it can use member functions)。
根据ADL规则,如果非成员函数想和类型一起被使用,应该将它们置于同一个名字空间中。换句话说,和类型X放在同一名字空间下的非成员函数,也是X接口的一部分。(常见的有<<or>>操作符)
示例:
#include <iostream>
//class N // 类域
//{
//public :
// enum E {e1};
// void f(E)
// {
// std::cout<< "N::f(N::E) called/n";
// }
//};
namespace N{ // 名字空间域
enum E {e1};
void f(E){
std::cout<< "N::f(N::E) called/n";
}
}
void f(int)
{
std::cout <<" ::f(int) called/n";
}
int main()
{
::f(N::e1); // 受限函数,禁用ADL //输出::f(int) called
f(N::e1); // 普通查找到f();
return 0;
}
上述例子,如果N为class,输出为:::f(int) called;如果N为名字空间,输出:N::f(N::E) called。
也就是说ADL仅会将参数所在的名字空间中的函数名字加入查找范围。
调用函数时,显式地限定名字空间将禁用ADL查找,加快解析过程。