Co to jest „alias przestrzeni nazw” w C ++?

156

Co to jest „alias przestrzeni nazw” w C ++? Jak to jest używane?

Martin B.
źródło

Odpowiedzi:

186

Alias ​​przestrzeni nazw to wygodny sposób odwoływania się do długiej nazwy przestrzeni nazw za pomocą innej, krótszej nazwy.

Na przykład załóżmy, że chcesz użyć wektorów numerycznych z uBLAS firmy Boost bez using namespacedyrektywy. Podawanie pełnej przestrzeni nazw za każdym razem jest uciążliwe:

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

Zamiast tego możesz zdefiniować alias dla boost::numeric::ublas- powiedzmy, że chcemy to skrócić do ublas:

namespace ublas = boost::numeric::ublas;


ublas::vector<double> v;
Martin B.
źródło
7
Aby ewentualnie wyjaśnić negatywne głosy, SO nie jest i nigdy nie zastąpi v dobrego podręcznika C ++. Każda taka książka odpowie na zadane przez Ciebie pytanie. A więc „cecha” odpowiadania na własne pytania nie powinna być wykorzystywana do przedstawiania parafraz takich książek.
24
Bez urazy ... Żeby tylko wyjaśnić, dlaczego to zrobiłem: z komentarzy Joela w podcastie zrozumiałem, że nawet pytania „dla początkujących” były uczciwą grą na SO i że zadawanie pytań i odpowiadanie na nie jest dopuszczalne siebie, jeśli ta zawartość nie była jeszcze na SO w przystępnej formie. Ale najwyraźniej jest to źle widziane?
Martin B
1
Z pewnością istnieje etykieta, aby odpowiedzieć na własne pytanie, aby uniknąć irytacji; w tym przypadku jest całkiem oczywiste, że nigdy nie było to prawdziwe pytanie. Na przykład stackoverflow.com/questions/494927/…
Marc Gravell
6
@Martin B: Nie zgadzam się, że jest to pytanie na poziomie podstawowym - w rzeczywistości w przeszłości zadawano znacznie bardziej oczywiste pytania i otrzymywano wiele głosów. Powiedziawszy to, ludzie mogą poczuć, że po prostu próbujesz zdobyć sobie reputację. Sposobem na obejście tego jest oznaczenie jednego lub obu pytań / odpowiedzi jako „wiki społeczności”. Osobiście zadałbym pytanie jako ty i odpowiedziałbym jako społeczność. Jeśli pytanie jest merrit, uzyskasz zwrot z inwestycji.
Richard Corden,
1
Myślę, że ważne pytanie brzmi: czy to pytanie jest prawdziwe "- czy jest to coś, o co ktoś cię zadał? Czy jest to coś, o czym ludzie chcą wiedzieć? Czy jest to coś, na co nie zadano jeszcze odpowiedzi w SO? Jeśli czytasz wpis na blogu SO dotyczący publikowania i odpowiadania na pytania przez społeczność R tutaj, zauważ, że wybrali X najpopularniejszych pytań, które ich społeczność faktycznie zadawała , więc miał on znaczenie w świecie rzeczywistym. Wydaje się, że losowe fragmenty wiedzy specyficznej dla języka i umieszczanie ich tutaj wydaje się mniej przydatne
jalf
7

Po prostu #define nie zadziała.

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

Kompiluje się dobrze. Umożliwia obejście kolizji nazw przestrzeni nazw / klas.

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

W ostatnim wierszu „Hmm: Ups” to błąd kompilacji. Preprocesor zmienia go na Nope :: Oops, ale Nope jest już nazwą klasy.

user2168377
źródło
3
Co #define? Być może Twoja odpowiedź odnosi się do poprzedniej wersji pytania?
einpoklum
3

Należy również zauważyć, że aliasy przestrzeni nazw i dyrektywy using są rozwiązywane w czasie kompilacji, a nie w czasie wykonywania. (Mówiąc dokładniej, oba są narzędziami używanymi do informowania kompilatora, gdzie jeszcze ma szukać podczas rozwiązywania nazw, jeśli nie może znaleźć określonego symbolu w bieżącym zakresie lub w żadnym z jego zakresów nadrzędnych). Na przykład żadne z nich nie będzie skompilować:

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;

Zaciekawiony umysł mógł zauważyć, że constexprzmienne są również używane w czasie kompilacji i zastanawiać się, czy można ich używać w połączeniu z aliasem lub dyrektywą. O ile wiem, nie mogą, chociaż mogę się co do tego mylić. Jeśli musisz pracować ze zmiennymi o identycznych nazwach w różnych przestrzeniach nazw i wybierać między nimi dynamicznie, musisz użyć odwołań lub wskaźników.

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

Użyteczność powyższego może być ograniczona, ale powinna służyć temu celowi.

(Przepraszam za wszelkie literówki, które mogłem pominąć w powyższym.)

Justin Time - Przywróć Monikę
źródło
0

Przestrzeń nazw służy do zapobiegania konfliktom nazw.

Na przykład:

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

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

Masz teraz pasek nazw dwóch klas, które są zupełnie inne i oddzielne dzięki przestrzeni nazw.

Pokazane "używanie przestrzeni nazw" polega na tym, że nie musisz określać przestrzeni nazw, aby używać klas w tej przestrzeni nazw. tj. std :: string staje się ciągiem.

mój zasób: https://www.quora.com/What-is-namespace-in-C++-1

mai
źródło