2015-05-27 23 views
9

Questo file ++ c ...Perché lo spazio dei nomi non è stato aggiunto alla funzione quando si utilizza la direttiva namespace?

namespace foo { 
    class C { 
     void m(); 
    }; 
    void f(); 
} 

using namespace foo; 

void C::m() {} 
void f() {} 

..Compiles in un file oggetto con questi simboli:

$ g++ foo.cpp -c 
$ nm foo.o -C 
000000000000000a T f() 
0000000000000000 T foo::C::m() 

Perché C::m()? ottenere il namespace anteposto, ma non f()?

(I I al posto di using namespace foo uso namespace foo {...} poi entrambi i nomi ha foo anteporre).

+0

Come la risposta mostra, non essere avventato a saltare alle conclusioni quando scrivi domande. Se qualcosa è sorprendente, è meglio stare attenti a come ci si avvicina all'apparente contraddizione e chiedere qualcosa come "Il collegamento è diverso?" piuttosto che supponendo che lo faccia (poiché in effetti il ​​collegamento non ha nulla a che fare con la tua situazione, tutti i collegamenti coinvolti sono esterni). –

+1

@KerrekSB Ho aggiornato il titolo per non fare supposizioni sulla causa. (Troppo spesso mischia link, scope e allocazione dello storage quando si ha a che fare con C++). –

+0

Molto apprezzato! –

risposta

12

In void C::m() {}, C::m è un nome qualificato e tale definizione si riferisce sempre a qualcosa precedentemente dichiarato. Il compilatore cerca C, rileva cheè in realtà foo::C, grazie alla utilizzando la direttiva e che corrisponde a void C::m(){} come definizione di foo::C::m().

Quando si scrive void f() {}, questo è un nome non qualificato e dichiara sempre la funzione nello spazio dei nomi corrente, che è lo spazio dei nomi globale.