引數依賴查詢
在沒有顯式名稱空間限定符的情況下呼叫函式時,如果該函式的某個引數型別也在該名稱空間中,則編譯器可以選擇在名稱空間中呼叫函式。這稱為 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"
}