引數依賴查詢

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