1,什么是Argument-dependent lookup?
Argument-dependent lookup又被称为ADL,或者Koening lookup.是在 函数表达式调用(function-call expressions) 过程中查找 unqualified function names 的查找规则之一(其中该查找规则包含从重载函数中选择最佳的调用).
ADL使得使用定义在不同namespace的operators成为可能.
#include <iostream>
int main()
{
std::cout << "Test\n"; // There is no operator<< in global namespace, but ADL
// examines std namespace because the left argument is in
// std and finds std::operator<<(std::ostream&, const char*)
operator<<(std::cout, "Test\n"); // same, using function call notation
// however,
std::cout << endl; // Error: 'endl' is not declared in this namespace.
// This is not a function call to endl(), so ADL does not apply
endl(std::cout); // OK: this is a function call: ADL examines std namespace
// because the argument of endl is in std, and finds std::endl
(endl)(std::cout); // Error: 'endl' is not declared in this namespace.
// The sub-expression (endl) is not a function call expression
return 0;
}
2, 哪些情况下不会触发ADL?
通常这些需要的ODR(One Definition Rule).
(1),一个class/struct的成员(member data/function)的声明.
(2),一个声明在普通的作用域的块内的函数.
(2),任何不是函数/模板函数的声明.
3, 在函数调用表达式的创建过程中所依赖的类型的哪些namespace和class会被加入ADL集合?
(1), 基础类型(int, double...)需要被查找的namespace和class为空.
(2), class类型的参数需要被查找的namespace和class包含:
1), 该class本身
2), 该class的基类
3), 如果该class是另外一个class的member class,那么也包含该class上层class.
4), 以及该类所在的namespace
(3), class template specialization除了(2)中那些以外还包含有:
1), 该class template specialization时候的type.
如果该type是个non-type(比如:Test<2>)那么不在需要再把该type的namespace和 class计入ADL set.
如果该type是个template template parameters那么需要再把该type的namespace和 class计入ADL set.
2), 该class template specialization时候的type arguments的namespaces也会会被加入ADL set.
3), 该class template specialization时候的type arguments的classes也会被加入到ADL set.