2012-12-16 7 views
6

Nach 7.3.1.2 Namespace Mitglied Definitionen in C++ Norm ISO/IEC 14882: 2003 (E)C++ Forward-Deklaration und Freundschaft in Namespace

Jeder Name zuerst in einem Namespace deklariert ist ein Mitglied dieser Namespace . Wenn eine Friend-Deklaration in einer nicht-lokalen Klasse zuerst eine Klasse oder Funktion deklariert (dies bedeutet, dass der Name der Klasse oder Funktion nicht qualifiziert ist), ist die Friend-Klasse oder -Funktion ein Member von der innerste umschließende Namespace.

// 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 
} 

Seit void h(int); zuerst im globalen Namespace deklariert ist, ist es ein Mitglied des globalen Namespace. Warum wird die Friend-Deklaration friend void h(int); in nicht als ::h betrachtet, sondern als A::h?

+0

Sie erklären gerade einen void Freund auf der Klasse X. Wenn es etwas anderes tun würde, wäre ich besorgt. void h (int) Vorher wird im globalen Bereich angegeben, Y jedoch eindeutig im Namensbereich A. – Jay

Antwort

2

Am Ende des Absatzes heißt es:

Wenn Sie nach einer vorherigen Anmeldung einer Klasse oder einer Funktion deklariert als Freund suchen, und wenn der Name des Freundes Klasse oder eine Funktion ist weder Ein qualifizierter Name oder eine Vorlage-ID, Bereiche außerhalb des innersten umschließenden Namespace werden nicht berücksichtigt.

Deshalb wird ::h nicht berücksichtigt: Es ist weder ein qualifizierter Name noch eine Vorlage-ID. Aus diesem Grund wird auch ':: f2` betrachtet, da es sich um eine Template-ID handelt.

1

Ich denke, die inneren Deklarationen beschatten diejenigen im globalen Namespace. Außerdem sind die Friend-Deklarationen selbst Forward-Deklarationen, so dass sie die im globalen Namespace abbilden und nicht nur auf diese Funktionen verweisen.

zu 3.3.10.1 "Namen Versteck" in Bezug N3485:

Ein Name durch eine explizite Angabe des gleichen Namen in einer verschachtelten deklarativen Region oder abgeleiteten Klasse (10.2) ausgeblendet werden kann.

11.3.4 Freunde:

Eine Funktion in einem Freund Deklaration erste externe Bindung hat (3.5). Andernfalls behält die Funktion ihre vorherige Verknüpfung bei (7.1.1).

Mit Blick auf 3.5.2:

Wenn ein Name externe Bindung hat, ist es das Unternehmen kann bezeichnet wird bezeichnet durch Namen von Umfängen anderer Übersetzungseinheiten oder von anderen Bereichen der gleichen Übersetzungseinheit.