2012-06-07 19 views
9

Im próbuje zdefiniować funkcję klasa przyjaciela poza nazw tak:klasa przyjaciel funkcja wewnątrz przestrzeni nazw

namespace A{ 
class window{ 
    private: 
    int a; 
    friend void f(window); 
}; 
} 

void f(A::window rhs){ 
cout << rhs.a << endl; 
} 

Im uzyskiwanie błąd, że istnieje niejasność. i jest dwóch kandydatów: void A::f(A::window); i void f(A::window). Więc moje pytanie brzmi:

1) Jak sprawić, by globalna funkcja była przyjazna dla klasy A :: okno.

EDIT: (Po przeczytaniu odpowiedzi)

2) Dlaczego muszę zakwalifikować funkcję składową f wewnątrz klasy okna, aby być globalny wykonując ::f(window)?

3) dlaczego muszę wstępnie odgadnąć funkcję f (A :: window) w tym konkretnym przypadku, podczas gdy gdy klasa nie jest zdefiniowana wewnątrz przestrzeni nazw, to jest OK, aby funkcja była deklarowana po zadeklarowaniu funkcji przyjaciel.

Odpowiedz

15

Jak również dodanie :: potrzebne do przekazania zadeklarować, np .:

namespace A { class window; } 

void f(A::window); 

namespace A{ 
    class window{ 
    private: 
    int a; 
    friend void ::f(window); 
    }; 
} 

void f(A::window rhs){ 
    std::cout << rhs.a << std::endl; 
} 

Zauważ, że dla tej deklaracji w przód do pracy potrzebne do przekazania zadeklarować klasę też!

+0

więc :: prefiks dostęp do globalnej przestrzeni nazw to taka, która wymaga pre deklarowana funkcja void f (A :: window); czy to jest poprawne. z góry dziękuję. – AlexDan

+0

Tak to działa, gdy funkcja zwraca pustkę. Ale co jeśli zwróci instancję klasy, powiedzmy B? Następnie kompilator rzuca się na "przyjaciela B :: f()", ponieważ uważa, że ​​mamy na myśli "B :: f()" (tj. Funkcję klasy B, w przeciwieństwie do funkcji globalnej). Jakieś rozwiązanie tego? –

+0

Nie widzę, jak można legalnie łączyć nazwy - czy możesz pokazać to na czymś takim jak ideone? – Flexo

4

Należy to zrobić: trzeba naprzód deklaruje jasno f jest w globalnej przestrzeni nazw (a nie pliku statycznego):

#include <string> 
#include <iostream> 

using namespace std; 

////// forward declare magic: 

namespace A{ class window; }  
void f(A::window rhs); 

////// 

namespace A { 
    class window { 
     private: 
      int a; 
      friend void ::f(window); 
    }; 
} 

void f(A::window rhs) { 
    cout << rhs.a << endl; 
} 

int main() 
{ 
} 
Powiązane problemy