Odpowiedzi:
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 namespace
dyrektywy. 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;
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.
Więcej na ten temat http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-C-1-of-n
Chodzi o wybranie aliasu dla dłuuugiej nazwy przestrzeni nazw, takiej jak:
namespace SHORT = NamespaceFirst::NameSpaceNested::Meow
Później możesz wpisaćef
typedef SHORT::mytype
zamiast
typedef NamespaceFirst::NameSpaceNested::Meow::mytype
Ta składnia działa tylko dla przestrzeni nazw, nie może zawierać klas, typów po namespace NAME =
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 constexpr
zmienne 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.)
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.