2012-12-16 11 views
6

według 7.3.1.2 definicje członkowskie nazw w C++ standard ISO/IEC 14882: 2003 (E)C++ deklaracja Forward i Przyjaźni w obszarze nazw

Każda nazwa pierwsza zadeklarowana w przestrzeni nazw jest członkiem tej nazw . Jeśli deklaracja znajomego w klasie nielokalnej najpierw deklaruje klasę lub funkcję (co oznacza, że ​​nazwa klasy lub funkcja jest niekwalifikowalna), klasa lub funkcja przyjaciela jest członkiem najgłębiej otaczającej przestrzeni nazw.

// Assume f and g have not yet been defined. 
void h(int); 
template <class T> void f2(T); 
namespace A { 
    class X { 
    friend void f(X); // A::f(X) is a friend 
     class Y { 
     friend void g(); // A::g is a friend 
     friend void h(int); // A::h is a friend 
     // ::h not considered 
     friend void f2<>(int); // ::f2<>(int) is a friend 
     }; 
    }; 
    // A::f, A::g and A::h are not visible here 
    X x; 
    void g() { f(x); } // definition of A::g 
    void f(X) { /* ... */} // definition of A::f 
    void h(int) { /* ... */ } // definition of A::h 
    // A::f, A::g and A::h are visible here and known to be friends 
} 

Od void h(int); najpierw deklarowane w globalnej przestrzeni nazw, jest członkiem globalnej przestrzeni nazw. Dlaczego deklaracja przyjaciela jest bardziej szczegółowa niż A::h, a nie ?

+0

Po prostu deklarujesz voidowi przyjaciela na X klasie. Gdyby zrobił coś jeszcze, byłbym zmartwiony. void h (int) Deklarowane wcześniej jest w globalnym, ale Y jest wyraźnie w przestrzeni nazw A. – Jay

Odpowiedz

2

Na końcu akapitu stwierdza:

Gdy szukasz wcześniejszej deklaracji klasy lub funkcji zadeklarowanej jako przyjaciela, a gdy nazwa klasy znajomego lub funkcji nie jest ani nazwa kwalifikowana ani identyfikator szablonu, zakresy poza najbardziej wewnętrzną otaczającą przestrzenią nazw nie są brane pod uwagę.

Dlatego nie jest brany pod uwagę ::h: Nie jest to ani nazwa kwalifikowana, ani identyfikator szablonu. Dlatego też rozważa się ":: f2", ponieważ jest to identyfikator szablonu.

1

Myślę, że wewnętrzne deklaracje śledzą te w globalnej przestrzeni nazw. Ponadto same deklaracje znajomych są deklaracjami forward, więc śledzą te w globalnym obszarze nazw, a nie tylko "odwołują się" do tych funkcji.

Nawiązując do 3.3.10.1 „Nazwa ukryciu” w N3485:

Nazwa może być ukryte przez wyraźnej deklaracji tej samej nazwie w zagnieżdżonego regionu deklaratywnej lub klasy pochodnej (10,2).

11.3.4 Znajomi:

Funkcja pierwsza zadeklarowana w deklaracji przyjaciel ma powiązania zewnętrzne (3.5). W przeciwnym razie funkcja zachowuje swoje poprzednie połączenie (7.1.1).

Patrząc na 3.5.2:

Kiedy nazwa ma powiązania zewnętrzne, jednostka to oznacza może być mowa o nazwach od zakresów innych jednostek tłumaczeniowych lub z innych zakresów samo jednostka tłumaczeniowa.

Powiązane problemy