Ответы:
Псевдоним пространства имен - это удобный способ ссылки на длинное имя пространства имен с помощью другого более короткого имени.
Например, скажем, вы хотели использовать числовые векторы из uBLAS Boost без using namespace
директивы. Указывать полное пространство имен каждый раз громоздко:
boost::numeric::ublas::vector<double> v;
Вместо этого вы можете определить псевдоним для boost::numeric::ublas
- скажем, мы хотим сократить это до просто ublas
:
namespace ublas = boost::numeric::ublas;
ublas::vector<double> v;
Проще говоря, #define не будет работать.
namespace Mine { class MyClass { public: int i; }; }
namespace His = Mine;
namespace Yours { class Mine: public His::MyClass { void f() { i = 1; } }; }
Компилирует нормально. Позволяет работать с конфликтами имен пространств / классов.
namespace Nope { class Oops { public: int j; }; }
#define Hmm Nope
namespace Drat { class Nope: public Hmm::Oops { void f () { j = 1; } }; }
В последней строке "Hmm: Oops" - ошибка компиляции. Препроцессор меняет его на Nope :: Oops, но Nope уже является именем класса.
Больше на эту тему http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-C-1-of-n
Все дело в выборе псевдонима для длинного имени пространства имен, такого как:
namespace SHORT = NamespaceFirst::NameSpaceNested::Meow
Затем позже вы можете набрать
typedef SHORT::mytype
вместо того
typedef NamespaceFirst::NameSpaceNested::Meow::mytype
Этот синтаксис работает только для пространств имен, не может включать классы, типы после namespace NAME =
Также обратите внимание, что псевдонимы пространства имен и использование директив разрешаются во время компиляции, а не во время выполнения. (Точнее, оба они используются для указания компилятору, где еще искать при разрешении имен, если он не может найти определенный символ в текущей области или какой-либо из своих родительских областей.) Например, ни один из них не будет компиляции:
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;
Теперь любопытный ум мог заметить, что constexpr
переменные также используются во время компиляции, и задаться вопросом, могут ли они использоваться в сочетании с псевдонимом или директивой. Насколько мне известно, они не могут, хотя я могу ошибаться по этому поводу. Если вам нужно работать с переменными с одинаковыми именами в разных пространствах имен и выбирать между ними динамически, вам придется использовать ссылки или указатели.
// 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;
}
}
Полезность вышесказанного может быть ограничена, но она должна служить цели.
(Мои извинения за любые опечатки, которые я, возможно, пропустил выше.)
Пространство имен используется для предотвращения конфликтов имен.
Например:
namespace foo {
class bar {
//define it
};
}
namespace baz {
class bar {
// define it
};
}
Теперь у вас есть две строки имен классов, которые совершенно разные и отдельные благодаря пространству имен.
«Использование пространства имен», которое вы показываете, заключается в том, что вам не нужно указывать пространство имен для использования классов в этом пространстве имен. то есть std :: string становится строкой.
мой ресурс: https://www.quora.com/What-is-namespace-in-C++-1