2011-07-28 45 views
2

我讀C++引物和筆者說,定義名稱空間內類的friend函數。

「如果一個類被命名空間中定義的,那麼否則 未申報的朋友 功能在同一個命名空間中聲明:

 namespace A { 
     class C { 
      public: 
      friend void f(const C&); // makes f a member of namespace A 
     }; 
     } 

難道不是意味着我沒有命名空間內再次聲明函數f()?

當我簡單地命名空間之外定義函數f()小號

void 
A::f(const C& obj) 
{ 
    std::cout << "f(const C&) " << std::endl; 
} 

我從G ++ 4.5話說錯誤,

FriendDeclarations1.cpp:40:23: error: ‘void A::f(const A::C&)’ should have been declared inside ‘A’ 

誰能告訴我這是什麼筆者意味着什麼呢?

回答

0

你有什麼有被解釋爲一個類的成員定義,類聲明,看起來像這樣:

class A { 
    void f(const C& obj); 
} 

你應該將f這樣:

namespace A { 
    void f(const C& obj) 
    { 
    std::cout << "f(const C&) " << std::endl; 
    } 
} 
3

什麼作者手段如果沒有明確聲明它的名稱空間,那麼朋友函數會在同一個類名稱空間中隱式聲明。

所以f需要命名空間中定義的A

#include <iostream> 

namespace A { 
    class C { 
    friend void f(const C&); // makes f a member of namespace A 
    int i; 

    public: 
     C() : i(42) {} 
    }; 

    void f(const A::C& obj) 
    { 
    std::cout << "f(const A::C&) " << std::endl; 
    std::cout << "obj.i = " << obj.i << std::endl;  // access private member 
    } 
} 

int main() 
{ 
    A::C ac; 

    f(ac); 
    return 0; 
} 

您可以通過明確聲明f屬於

#include <iostream> 

// forward declarations 
namespace A { class C; } 
namespace B { void f(const A::C&); } 

namespace A { 
    class C { 
    friend void B::f(const C&); 
    int i; 

    public: 
    C() : i(42) {} 
    }; 
} 

namespace B { 
    void f(const A::C& obj) 
    { 
    std::cout << "f(const A::C&) " << std::endl; 
    std::cout << "obj.i = " << obj.i << std::endl;  // access private member 
    } 
} 

int main() 
{ 
    A::C ac; 

    B::f(ac); 
    return 0; 
} 
2

標準7.3.1.2/3的命名空間改變這種行爲:

首先在名稱空間中聲明的每個名稱都是該名稱空間的成員。如果非本地類中的朋友聲明首先聲明一個類或函數83),則該朋友類或函數是最內層的名稱空間的成員。 直到在該名稱空間範圍內提供了匹配聲明(無論是在聲明授予友誼的類聲明之前還是之後),才能通過簡單名稱查找找到該朋友的名稱。