В С++, что такое "псевдоним пространства имен"?

Что такое псевдоним пространства имен в С++? Как он используется?

Ответ 1

Псевдоним пространства имен является удобным способом обращения к длинному имени пространства имен с помощью другого более короткого имени.

В качестве примера скажем, вы хотели использовать числовые векторы из Boost uBLAS без директивы using namespace. Определение полного пространства имен каждый раз громоздко:

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

Вместо этого вы можете определить псевдоним для boost::numeric::ublas - скажем, мы хотим сократить это до всего лишь ublas:

namespace ublas = boost::numeric::ublas;


ublas::vector<double> v;

Ответ 2

Проще говоря, #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 уже является именем класса.

Ответ 3

Подробнее об этом http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-C-1-of-n

Это все о выборе псевдонима для имени пространства имен looong, например:

namespace SHORT = NamespaceFirst::NameSpaceNested::Meow

Затем позже вы можете typedef

typedef SHORT::mytype

вместо

typedef NamespaceFirst::NameSpaceNested::Meow::mytype

Этот синтаксис работает только для пространств имен, не может включать классы, типы после namespace NAME =

Ответ 4

Также обратите внимание, что псевдонимы пространства имен и используемые директивы разрешаются во время компиляции, а не во время выполнения. (Более конкретно, они оба являются инструментами, используемыми для указания компилятору, где еще нужно искать при разрешении имен, если он не может найти конкретный символ в текущей области видимости или в любой из его родительских областей.) Например, ни один из них не будет компиляции:

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

Полезность вышеуказанного может быть ограничена, но она должна служить цели.

(Мои извинения за любые типографки, которые я, возможно, пропустил в приведенном выше.)