ADL机制

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。

参考: