参数依赖查找
在没有显式名称空间限定符的情况下调用函数时,如果该函数的某个参数类型也在该名称空间中,则编译器可以选择在名称空间中调用函数。这称为 Argument Dependent Lookup
或 ADL:
namespace Test
{
int call(int i);
class SomeClass {...};
int call_too(const SomeClass &data);
}
call(5); //Fails. Not a qualified function name.
Test::SomeClass data;
call_too(data); //Succeeds
call
失败,因为它的参数类型都不是来自 Test
名称空间。call_too
有效,因为 SomeClass
是 Test
的成员,因此它符合 ADL 规则。
什么时候不发生 ADL
如果正常的非限定查找找到类成员,已在块作用域声明的函数或不属于函数类型的函数,则不会发生 ADL。例如:
void foo();
namespace N {
struct X {};
void foo(X ) { std::cout << '1'; }
void qux(X ) { std::cout << '2'; }
}
struct C {
void foo() {}
void bar() {
foo(N::X{}); // error: ADL is disabled and C::foo() takes no arguments
}
};
void bar() {
extern void foo(); // redeclares ::foo
foo(N::X{}); // error: ADL is disabled and ::foo() doesn't take any arguments
}
int qux;
void baz() {
qux(N::X{}); // error: variable declaration disables ADL for "qux"
}