In C ++, che cos'è un "alias dello spazio dei nomi"?


156

Che cos'è un "alias dello spazio dei nomi" in C ++? Come si usa

Risposte:


186

Un alias dello spazio dei nomi è un modo conveniente per fare riferimento a un nome di spazio dei nomi lungo con un nome diverso e più corto.

Ad esempio, supponiamo che tu voglia utilizzare i vettori numerici di uBLAS di Boost senza una using namespacedirettiva. Dichiarare l'intero spazio dei nomi ogni volta è ingombrante:

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

Invece, puoi definire un alias per boost::numeric::ublas- diciamo che vogliamo abbreviare questo per solo 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 ++. Alla domanda che hai posto verrà data risposta da tale libro. E la "caratteristica" SO di rispondere alle tue domande non dovrebbe essere utilizzata per fornire parafrasi di tali libri.

24
Senza offesa ... Giusto per spiegare perché l'ho fatto: ho capito dai commenti di Joel sul podcast che anche le domande "entry-level" erano un gioco equo su SO, e che era accettabile porre una domanda e rispondere te stesso se quel contenuto non era ancora su SO in una forma accessibile. Ma a quanto pare, questo è malvisto?
Martin B

1
C'è sicuramente un galateo nel rispondere alla tua domanda, per evitare irritazioni; in questo caso, è abbastanza ovvio che non è mai stata una vera domanda. Ad esempio, stackoverflow.com/questions/494927/...
Marc Gravell

6
@Martin B: Non sono d'accordo sul fatto che si tratti di una domanda di livello base, infatti in passato sono state poste molte più ovvie domande in passato con molti voti. Detto questo, le persone potrebbero pensare che stai semplicemente cercando di guadagnare reputazione per te stesso. Un modo per aggirare questo è quello di contrassegnare una o entrambe le domande / risposte come "wiki della comunità". Personalmente andrei con domande come te e rispondere come comunità. Se la domanda ha allegria, otterrai ROI.
Richard Corden,

1
Penso che la domanda importante sia se la domanda è reale "- è qualcosa che ti è stato chiesto? È qualcosa che la gente vuole sapere? È qualcosa che non è già stato chiesto e risposto su SO? Se leggi il post sul blog SO sulla pubblicazione della community R e sulla risposta alle domande qui, nota che hanno raccolto le prime X domande che la loro community ha continuato a porre , quindi aveva rilevanza nel mondo reale. Prendere frammenti casuali di conoscenza specifica della lingua e postarle qui sembra meno utile
jalf

7

Molto semplicemente, #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 di spazi / classi.

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

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


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

3

Maggiori informazioni 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 spazio dei nomi looong, come:

namespace SHORT = NamespaceFirst::NameSpaceNested::Meow

Successivamente, è possibile digitare

typedef SHORT::mytype

invece di

typedef NamespaceFirst::NameSpaceNested::Meow::mytype

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


3

Si noti inoltre che gli alias dello spazio dei nomi e l'utilizzo delle direttive vengono risolti in fase di compilazione, non in fase di esecuzione. (Più specificamente, sono entrambi strumenti usati per dire al compilatore dove altro cercare quando si risolvono i nomi, se non riesce a trovare un simbolo particolare nell'ambito corrente o in uno dei suoi ambiti padre. Ad esempio, nessuno di questi compilare:

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 potrebbe aver notato che le constexprvariabili vengono utilizzate anche in fase di compilazione e si chiede se possano essere utilizzate insieme a un alias o una direttiva. Per quanto ne sappia, non possono, anche se potrei sbagliarmi al riguardo. Se devi lavorare con variabili con nome identico in spazi di nomi diversi e sceglierle tra loro dinamicamente, dovresti usare 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 limitata, ma dovrebbe servire allo scopo.

(Mi scuso per eventuali errori di battitura che potrei aver perso in quanto sopra.)


0

Lo spazio dei nomi viene utilizzato per prevenire conflitti di nomi.

Per esempio:

namespace foo {
    class bar {
        //define it
    };
}

namespace baz {
    class bar {
        // define it
    };
}

Ora hai due classi di nomi, completamente diverse e separate grazie allo spazio dei nomi.

Lo "usa lo spazio dei nomi" che mostri è in modo che non devi specificare lo spazio dei nomi per usare le classi all'interno di quello spazio dei nomi. cioè std :: string diventa stringa.

la mia risorsa: https://www.quora.com/What-is-namespace-in-C++-1

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.