編譯器的一個重要工作是解析它所遇到的名稱,一般而言,編譯器是按順序解析所遇到的名稱的,比如說,編譯器遇到一個函數,那麼就會為這個函數生成代碼,但是如果這個函數調用了另外一個的函數,而這個函數還沒有被解析過,那麼編譯器就會報錯,比如下面的例子:
void h() { f(); } void f() { cout<<"f()"<因為編譯器先遇到了h(),但是當它開始解析h()的時候,發現了一個還沒有被解析過的f(),所以就會報錯,如果把f()的定義放在h()之前就沒有問題了。這是一般的情況,編譯器理應更聰明一點,所以就有了ADL,即關聯參數查找,也就是說編譯器會查找與函數的參數相關聯的作用域,比較下面兩個例子就可以發現這一點:
例1:
test1.cpp
class A { int i; public: friend void f(); }; int main(void) { f(); return 0; }tesp2.cppclass A; void f() {}使用如下命令編譯時會出現"找不到 f "的錯誤:g++ -o test1.cpp test2.cpp,再來看第二個例子:例2:
test1.cpp
class A { int i; public: friend void f(A &a); }; int main(void) { A a; f(a); return 0; }test2.cppclass A; void f(A &a) {}現在再使用相同的命令來編譯就沒有錯誤了