ADL全称是Argument-Dependent Lookup。
比如下面的例子:
namespace MyNamespace {
class MyClass {
public:
int value;
};
std::ostream& operator<<(std::ostream& os, const MyClass& obj) {
os << "MyClass: " << obj.value;
return os;
}
}
int main() {
MyNamespace::MyClass obj;
obj.value = 42;
using std::cout; // Required to use 'cout' without fully qualifying it.
cout << obj << std::endl; // ADL is used to find the correct overloaded 'operator<<'.
}
In this example, when you call cout « obj; in main(), ADL is used to find the correct operator«() in the MyNamespace namespace because the argument obj is of type MyNamespace::MyClass.
另一个例子是:
std::cout << "Hello, world!" << std::endl; // 1
std::operator<<(std::cout, "Hello World!\n"); // 2
这里的第1个operator«没有指定namespace,为什么可以正常工作?
这是因为,第一种写法中,编译器发现流运算符的左参数 std::cout 是隶属于命名空间 std 中的,同时又因为编译器没有在全局中找到流运算符的定义,于是编译器就会把搜查范围扩展到命名空间 std ,继续搜索流运算符的定义,当然就成功找到了。也就是说,下面这种写法也是可以的:
#include <iostream> // for std::cout
int main() {
operator<<(std::cout, "Hello World!\n");
return 0;
}
!!! 在Copy and Swap中,也有用到ADL。
参考: