Was ist in C ++ ein "Namespace-Alias"?


Antworten:


186

Ein Namespace-Alias ​​ist eine bequeme Möglichkeit, einen langen Namespace-Namen durch einen anderen, kürzeren Namen zu referenzieren.

Angenommen, Sie möchten die numerischen Vektoren aus Boosts uBLAS ohne using namespaceDirektive verwenden. Es ist umständlich, jedes Mal den vollständigen Namespace anzugeben:

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

Stattdessen können Sie einen Alias ​​definieren für boost::numeric::ublas- sagen wir, wir möchten dies auf nur Folgendes abkürzen ublas:

namespace ublas = boost::numeric::ublas;


ublas::vector<double> v;

7
Um möglicherweise die Abstimmungen zu erklären, ist SO kein Ersatz für ein gutes C ++ - Lehrbuch und wird es auch nie sein. Die von Ihnen gestellte Frage wird von einem solchen Buch beantwortet. Und die SO "Funktion" zur Beantwortung Ihrer eigenen Fragen sollte nicht verwendet werden, um Paraphrasen solcher Bücher bereitzustellen.

24
Keine Beleidigung ... Nur um zu erklären, warum ich das getan habe: Aus Joels Kommentaren im Podcast ging hervor, dass selbst Fragen der Einstiegsklasse für SO ein faires Spiel waren und dass es akzeptabel war, eine Frage zu stellen und zu beantworten selbst, wenn dieser Inhalt noch nicht in einer zugänglichen Form auf SO war. Aber anscheinend ist das verpönt?
Martin B

1
Es gibt sicherlich eine Etikette, Ihre eigene Frage zu beantworten, um Irritationen zu vermeiden. in diesem Fall ist es ziemlich offensichtlich , dass es nie war eine echte Frage. Zum Beispiel stackoverflow.com/questions/494927/…
Marc Gravell

6
@ Martin B: Ich stimme nicht zu, dass dies eine Einstiegsfrage ist - tatsächlich wurden in der Vergangenheit viel offensichtlichere Fragen mit vielen Stimmen gestellt. Trotzdem haben die Leute vielleicht das Gefühl, dass Sie einfach versuchen, sich einen Namen zu machen. Eine Möglichkeit, dies zu umgehen, besteht darin, eine oder beide Fragen / Antworten als "Community-Wiki" zu markieren. Persönlich würde ich mit Fragen als Sie gehen und als Gemeinschaft antworten. Wenn die Frage Merrit hat, erhalten Sie einen ROI.
Richard Corden

1
Ich denke, die wichtige Frage ist, ob die Frage echt ist "- ist es etwas, das Ihnen gestellt wurde? Ist es etwas, das die Leute wissen wollen? Ist es etwas, das noch nicht auf SO gestellt und beantwortet wurde? Wenn Sie lesen Beachten Sie, dass der SO-Blog-Beitrag über das Posten und Beantworten von Fragen in der R-Community hier die Top-X-Fragen ausgewählt hat, die ihre Community tatsächlich immer wieder gestellt hat , sodass sie für die Praxis relevant sind. Es scheint, dass Sie zufällige Ausschnitte sprachspezifischen Wissens nehmen und hier posten weniger nützlich.
Jalf

7

Ganz einfach, das #define funktioniert nicht.

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

Kompiliert gut. Hiermit können Sie Kollisionen mit Namespace- und Klassennamen umgehen.

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

In der letzten Zeile ist "Hmm: Ups" ein Kompilierungsfehler. Der Vorprozessor ändert es in Nope :: Oops, aber Nope ist bereits ein Klassenname.


3
Was #define? Vielleicht bezieht sich Ihre Antwort auf eine frühere Version der Frage?
Einpoklum

3

Mehr zu diesem Thema http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-C-1-of-n

Es geht darum, einen Alias ​​für einen langen Namespace-Namen auszuwählen, z.

namespace SHORT = NamespaceFirst::NameSpaceNested::Meow

Dann können Sie später typedef

typedef SHORT::mytype

anstatt

typedef NamespaceFirst::NameSpaceNested::Meow::mytype

Diese Syntax funktioniert nur für Namespaces, kann keine Klassen und Typen nach dem enthalten namespace NAME =


3

Beachten Sie außerdem, dass Namespace-Aliase und die Verwendung von Anweisungen zur Kompilierungszeit und nicht zur Laufzeit aufgelöst werden. (Insbesondere werden beide Tools verwendet, um dem Compiler mitzuteilen, wo er beim Auflösen von Namen suchen soll, wenn er im aktuellen Bereich oder in einem seiner übergeordneten Bereiche kein bestimmtes Symbol finden kann.) Zum Beispiel wird keiner dieser Tools verwendet kompilieren:

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;

Nun hat ein neugieriger Verstand vielleicht bemerkt, dass constexprVariablen auch zur Kompilierungszeit verwendet werden, und sich gefragt, ob sie in Verbindung mit einem Alias ​​oder einer Direktive verwendet werden können. Meines Wissens können sie das nicht, obwohl ich mich vielleicht irre. Wenn Sie mit gleichnamigen Variablen in verschiedenen Namespaces arbeiten und dynamisch zwischen ihnen wählen müssen, müssen Sie Referenzen oder Zeiger verwenden.

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

Der Nutzen des Obigen mag begrenzt sein, sollte aber dem Zweck dienen.

(Ich entschuldige mich für Tippfehler, die ich oben möglicherweise übersehen habe.)


0

Der Namespace wird verwendet, um Namenskonflikte zu vermeiden.

Beispielsweise:

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

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

Sie haben jetzt zwei Klassen-Namensleisten, die dank des Namespaces völlig unterschiedlich und getrennt sind.

Der angezeigte "using namespace" dient dazu, dass Sie den Namespace nicht angeben müssen, um Klassen in diesem Namespace zu verwenden. dh std :: string wird string.

Meine Ressource: https://www.quora.com/What-is-namespace-in-C++-1

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.