2009-07-31 1 views

risposta

149

Un alias di uno spazio dei nomi è un modo conveniente di riferirsi a un nome di spazio dei nomi lungo con un nome diverso e più breve.

Ad esempio, si supponga di voler utilizzare i vettori numerici dell'UBLAS di Boost senza una direttiva using namespace. Affermare il pieno spazio dei nomi ogni volta che è ingombrante:

boost::numeric::ublas::vector<double> v; 

Invece, è possibile definire un alias per boost::numeric::ublas - dicono che vogliamo per abbreviare questo a poco ublas:

namespace ublas = boost::numeric::ublas; 


ublas::vector<double> v; 
+7

Per spiegare eventualmente i downvotes, SO non è e non sarà mai una sostituzione per un buon libro di testo C++. La domanda che hai posto sarà risolta da qualsiasi libro di questo tipo. E la "caratteristica" SO di rispondere alle tue domande non dovrebbe essere usata per fornire parafrasi di tali libri. –

+16

Senza offesa ... Solo per spiegare perché l'ho fatto: ho capito dai commenti di Joel nel podcast che anche le domande "entry-level" erano un gioco equo su SO, e che era accettabile porre una domanda e una risposta da solo se quel contenuto non era ancora in SO in una forma accessibile. Ma a quanto pare, questo è disapprovato? –

+1

C'è sicuramente un'etichetta per rispondere alla propria domanda, per evitare irritazioni; in questo caso, è abbastanza ovvio che non è mai stata ** una vera domanda. Ad esempio, http://stackoverflow.com/questions/494927/stack-overflow-etiquette-for-answering-your-own-question –

6

Molto semplicemente, la # define non funzionerà

namespace Mine { class MyClass { public: int i; }; } 
namespace His = Mine; 
namespace Yours { class Mine: public His::MyClass { void f() { i = 1; } }; } 

Compila bene. Ti consente di aggirare le collisioni di nomi/classi.

namespace Nope { class Oops { public: int j; }; } 
#define Hmm Nope 
namespace Drat { class Nope: public Hmm::Oops { void f() { j = 1; } }; } 

Sull'ultima riga, "Hmm: Oops" è un errore di compilazione. Il pre-processore lo cambia in Nope :: Oops, ma Nope è già un nome di classe.

+0

Così semplice ma al tempo stesso ingombrante ...;) – Hermes

+2

Cosa #define? Forse la tua risposta si riferisce a una versione precedente della domanda? – einpoklum

1

più su questo argomento http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-C-1-of-n

Si tratta solo di scegliere un alias per un nome di namespace luuungo, come ad esempio:

namespace SHORT = NamespaceFirst::NameSpaceNested::Meow

Poi, più tardi, è possibile typedef

typedef SHORT::mytype

anziché

typedef NamespaceFirst::NameSpaceNested::Meow::mytype

Questa sintassi funziona solo per gli spazi dei nomi, non può includere le classi, i tipi dopo la namespace NAME =

1

Si noti inoltre che gli alias namespace e utilizzando le direttive vengono risolti in fase di compilazione, non è il tempo di esecuzione. (Più in particolare, sono entrambi gli strumenti utilizzati per dire al compilatore dove altro da guardare quando risolvono i nomi, se non riesce a trovare un particolare simbolo nell'attuale ambito o in uno qualsiasi dei suoi ambiti genitore.) Ad esempio, nessuno di questi compilazione:

namespace A { 
    int foo; 
    namespace AA { 
     int bar; 
    } // namespace AA 
    namespace AB { 
     int bar; 
    } // namespace AB 
} // namespace A 
namespace B { 
    int foo; 
    namespace BA { 
     int bar; 
    } // namespace BA 
    namespace BB { 
     int bar; 
    } // namespace BB 
} // namespace B 

bool nsChooser1, nsChooser2; 
// ... 

// This doesn't work. 
namespace C = (nsChooser1 ? A : B); 
C::foo = 3; 

// Neither does this. 
// (Nor would it be advisable even if it does work, as compound if-else blocks without braces are easy to inadvertently break.) 
if (nsChooser1) 
    if (nsChooser2) 
     using namespace A::AA; 
    else 
     using namespace A::AB; 
else 
    if (nsChooser2) 
     using namespace B::BA; 
    else 
     using namespace B::BB; 

Ora, una mente curiosa notato che constexpr variabili sono utilizzati anche in fase di compilazione, e chiedere se possono essere utilizzati in combinazione con un alias o una direttiva. Per quanto ne so, non possono, anche se potrei sbagliarmi. Se è necessario lavorare con variabili con nomi identici in spazi dei nomi diversi e scegliere tra loro dinamicamente, è necessario utilizzare riferimenti o puntatori.

// Using the above namespaces... 
int& foo = (nsChooser1 ? A::foo : B::foo); 

int* bar; 
if (nsChooser1) { 
    if (nsChooser2) { 
     bar = &A::AA::bar; 
    } else { 
     bar = &A::AB::bar; 
    } 
} else { 
    if (nsChooser2) { 
     bar = &B::BA::bar; 
    } else { 
     bar = &B::BB::bar; 
    } 
} 

L'utilità di quanto sopra può essere limitato, ma dovrebbe servire allo scopo.

(Le mie scuse per eventuali errori di battitura che ho potuto perdere in quanto sopra.)