2015-09-28 51 views
1

以下代碼位於兩個源文件中。爲什麼找到f1但f2不是?

第一:

namespace A { 
    // two friends; neither is declared apart from a friend declaration 
    // these functions implicitly are members of namespace A 
    class C { 
     friend void f2();   // won’t be found, unless otherwise declared 
     friend void f1(const C&); // found by argument-dependent lookup 
    }; 
} 
int main() 
{ 
    A::C obj; 
    f1(obj);  // ok: find A::f through the friend declaration in A::C 
    A::f2();  // no member named f2 in namespace A 
} 

和第二:

#include <iostream> 
namespace A { 
    class C; 
    void f1(const C&) { 
     std::cout << 1; 
    } 
    void f2() { 
     std::cout << 2; 
    } 
} 

代碼的第一片選自C複製++引物,唯一的區別是C++底漆呼叫F2()無前綴命名空間。第二件是我的補充。我想知道現在F1F2隱含的命名空間的成員,爲什麼A :: F2()仍然是錯誤的,而F1(OBJ)可以通過ADL找到?

+0

我第一次遇到ADL ...我的反應大概會是「OHMYGODWHY」。 – Cubic

+1

@Cubic這樣'std :: cout <<'x';'起作用。沒有ADL你會寫是'使用std ::運算符<<'或'的std ::運算符<<(標準::法院, 'X');'等 –

回答

3

這是規則,在7.3.1.2中發現,導致A::f2()失敗:

如果非本地類朋友的聲明首先聲明一個類,函數,類模板或函數模板friend是最內層封閉名稱空間的成員。這個朋友聲明本身並不會讓這個名字對於不合格的查找(3.4.1)或合格的查找(3.4.3)可見。

+0

我仍然困惑爲什麼f1被ADL發現但f2不是?他們之間有什麼區別嗎?或者,您節選的最後一句,只是因爲F1是由ADL發現了什麼? – Sherwin

+0

@xlnwel:是的,ADL規則允許發現不能按名稱找到的東西。 –

+0

非常感謝你! – Sherwin

0

在第一個代碼塊中,f2位於A::C的詞彙範圍內,即該名稱在A::C的範圍內可見。它在A::C以外不可見。

要使f2A::C範圍外可見,您需要在A中聲明或定義它。

+0

但爲什麼F1是可見的??? – Sherwin

+0

'f1'被ADL發現。由於'f2'沒有任何說法,ADL不能用來尋找'f2'。 –

相關問題