2015-01-30 9 views
6

Abbiamo il seguente esempio da N4296::3.3.9/2 [basic.scope.temp]:regione dichiarativa di un parametro funzione

namespace N { 
    template<class T> struct A { };     // #1 
    template<class U> void f(U) { }     // #2 
    struct B 
    { 
     template<class V> friend int g(struct C*); // #3 
    }; 
} 

Le regioni dichiarativa di T, U e V sono il modello dichiarazione s su linee #1, #2 e #3, rispettivamente. Ma i nomi A, f, g e C tutto appartengono alla stessa regione dichiarativa - vale a dire, il namespace-corpo di N.

Non è chiaro perché N s corpo è la regione dichiarativa di g e C. Pensavo fosse il corpo della classe B s.
Qualcuno può chiarire cosa significa lo standard?

risposta

4

C viene dapprima dichiarato nella g, così [basic.scope.pdecl]/(7,2) si applica

un elaborato di tipo-specificatore della forma

                  chiave di classe identificatore

se il elaborato-type-specificatore è utilizzata nel decl-specificatore-seq o parametro dichiarazione clausola di una funzione definita in ambito namespace, [...]; altrimenti, ad eccezione di una dichiarazione di amico, , l'identificatore viene dichiarato nello spazio dei nomi o nell'ambito del blocco più piccolo che contiene la dichiarazione.

(Il "altrimenti ..." parte applica unicamente a dichiarazioni di forma friend class C;, utilizza "come" e non "dentro")
Così come C è dichiarata come membro di N, chiaramente la sua regione dichiarativa è il corpo di N. Infatti, è can use C outside B.

E g è un membro della N secondo [namespace.memdef]/3

Se una dichiarazione amico in una classe non locale dichiara prima un [..] modello di funzione l'amico è un membro dello spazio dei nomi più interno che include lo spazio dei nomi .

Così regione dichiarativa di g è anche N s' organismo.

2

Perché g è una funzione amico è scope è l'ambito dello spazio dei nomi, ai sensi dell'articolo 11.3Amici:

Una funzione può essere definita in una dichiarazione amico di una classe se e solo se la classe è una classe non locale (9.8), il nome della funzione è non qualificato e la funzione ha ambito spazio dei nomi. [Esempio:

class M { 
friend void f() { } // definition of global f, a friend of M, 
// not the definition of a member function 
}; 

-end esempio]

Possiamo vedere questo vale anche per funzionare i modelli dalla sezione 7.3.1.2:

Se una dichiarazione amico in una classe non-locale prima dichiara una classe, la funzione , il modello di classe o il modello di funzione l'amico è un membro dei nomi di chiusura più interni CE. [...]

e per C questa è fissata alla sezione 3.3.2 punto di dichiarazione:

Il punto di dichiarazione di una classe prima dichiarata in una elaborata tipo-specificatore è il seguente:

e comprende le seguenti proiettile (sottolineatura mia):

  • un elaborato di tipo-specificatore di forma

    classe identificatore

se il tipo-specificatore elaborato viene utilizzato nel decl-specificatore-seq o parametro -la clausola di dichiarazione di una funzione definita nello spazio dei nomi, l'identificatore è dichiarato come nome di classe nel namespace che contiene la dichiarazione;

+1

'g' è un modello di funzione, non una funzione. –

+0

@ T.C. punto equo, aggiunto ulteriori dettagli –

+0

@downvoter per favore spiega, questa è la seconda volta che qualcuno fa downvotes senza spiegazione e la prima volta è stato rimosso poco dopo. Si prega di spiegare qualsiasi problema. –

Problemi correlati