Що таке "псевдонім простору імен" у C ++?


Відповіді:


186

Псевдонім простору імен - це зручний спосіб посилатися на довге ім’я простору імен за допомогою іншого, коротшого імені.

Наприклад, скажіть, що ви хотіли використовувати числові вектори з uost Bost без using namespaceдирективи. Визначати повний простір імен кожного разу громіздко:

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

Натомість ви можете визначити псевдонім для boost::numeric::ublas- скажімо, ми хочемо скоротити це до ublas:

namespace ublas = boost::numeric::ublas;


ublas::vector<double> v;

7
Щоб можливо пояснити суттєві результати, ТАК не є і ніколи не стане заміною для хорошого підручника на C ++. На поставлене вами запитання відповість будь-яка така книга. І ТО "особливість" відповіді на ваші власні запитання не повинна використовуватися для надання переказів таких книг.

24
Без правопорушень ... Просто для пояснення, чому я це зробив: саме з коментарів Джоеля в подкасті я розумів, що навіть питання "початкового рівня" були чесною грою на SO, і що прийнятно задати питання і відповісти на нього себе, якщо цей вміст ще не був у доступному вигляді. Але, мабуть, це нахмурилося?
Мартін Б

1
Звичайно, є етикет, щоб відповісти на власне питання, щоб уникнути роздратування; в цьому випадку досить очевидно, що це ніколи не було справжнім питанням. Наприклад, stackoverflow.com/questions/494927 / ...
Марк Gravell

6
@Martin B: Я не погоджуюсь, що це питання початкового рівня - адже в минулому зараз було багато більш очевидних питань, на які було поставлено багато голосів. Сказавши це, люди можуть відчути, що ви просто намагаєтеся отримати собі репутацію. Шлях до цього - позначити одне або обидва питання / відповіді як "вікі спільноти". Особисто я б пішов з питанням як ви і відповідав як спільнота. Якщо питання має значення, тоді ви отримаєте рентабельність інвестицій.
Річард Корден

1
Я думаю, що важливе питання полягає в тому, чи справді це питання? "- це те, що вас запитали? Чи це щось хочуть знати люди? Це щось таке, про що вже не ставили запитання та відповіді на нього? Якщо ви читаєте публікація в блозі SO про публікацію спільноти R та відповідь на запитання тут, зауважте, що вони обрали основні X питання, які їх спільнота насправді продовжувала задавати , тому вони мали актуальне значення для реального світу. менш корисна.
jalf

7

Простіше кажучи, #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; } }; }

В останньому рядку "Хм: Ой" - помилка компіляції. Попередній процесор змінює його на Nope :: Oops, але Nope - це вже назва класу.


3
Що #define? Можливо, ваша відповідь стосується попередньої версії запитання?
einpoklum

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

Потім пізніше ви можете ввестиdef

typedef SHORT::mytype

замість

typedef NamespaceFirst::NameSpaceNested::Meow::mytype

Цей синтаксис працює лише для просторів імен, не може включати класи, типи після namespace NAME =


3

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

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

Корисність сказаного може бути обмеженою, але вона повинна служити меті.

(Мої вибачення за помилки, які я, можливо, пропустив у вищесказаному.)


0

Простір імен використовується для запобігання конфліктів імен.

Наприклад:

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

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

Тепер у вас є рядок імен двох класів, які абсолютно різні та відокремлені завдяки простору імен.

"Використання простору імен", яке ви показуєте, означає, що вам не потрібно вказувати простір імен, щоб використовувати класи в цьому просторі імен. тобто std :: string стає рядком.

мій ресурс: https://www.quora.com/What-is-namespace-in-C++-1

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.