Как вы импортируете перечисление в другое пространство имен в C ++? - PullRequest
28 голосов
/ 20 июля 2010

У меня есть enum в пространстве имен, и я хотел бы использовать его, как если бы он был в другом пространстве имен.Интуитивно я подумал, что мог бы использовать 'using' или 'typedef' для достижения этой цели, но ни один из них на самом деле не работал.Фрагмент кода, чтобы доказать это, протестировано на GCC и Sun CC:

namespace foo
{

enum bar {
    A
};

}

namespace buzz
{
// Which of these two methods I use doesn't matter,
// the results are the same.
using foo::bar;
//typedef foo::bar bar;
}

int main()
{
    foo::bar f; // works
    foo::bar g = foo::A; // works

    buzz::bar x; // works
    //buzz::bar y = buzz::A; // doesn't work
    buzz::bar z = foo::A;
}

Проблема в том, что само перечисление импортируется, но ни один из его элементов.К сожалению, я не могу изменить исходное перечисление, чтобы оно было заключено в дополнительное пустое пространство имен или класс, не нарушая много другого существующего кода.Лучшее решение, которое я могу придумать, это вручную воспроизвести перечисление:

namespace buzz
{
enum bar
{
    A = foo::A
};
}

Но оно нарушает принцип DRY .Есть ли лучший способ?

Ответы [ 5 ]

25 голосов
/ 20 июля 2010

Обернуть существующее пространство имен во вложенное пространство имен, которое вы затем «используете» в исходном пространстве имен.

namespace foo
{
    namespace bar_wrapper {
        enum bar {
            A
        };
    }
    using namespace bar_wrapper;
}

namespace buzz
{
    using namespace foo::bar_wrapper;
}
8 голосов
/ 20 июля 2010

Хотя мне больше всего нравится подход Mark B, поскольку он не нарушает существующий код, вы также можете сделать следующее:

namespace foo {
 enum bar {
  A, B [..]
 };
}

namespace buzz {
 using foo::bar;
 using foo::A;
 using foo::B;
 [..]
}
6 голосов
/ 20 июля 2010

Проблема здесь в том, что объявление using извлекает только имя перечисления, а не имена его значений. Enum не являются областями действия и не несут имен перечислителей .Я не думаю, что можно импортировать сами перечисляемые значения.Попробуйте обернуть перечисление в пространство структуры / имен и использовать его.

2 голосов
/ 01 марта 2018

Начиная с C ++ 11 вы можете использовать enum class. Импорт enum class импортирует все его значения:

namespace foo
{

enum class bar {
    A
};

}

namespace buzz
{
using foo::bar;
}

int main()
{
    foo::bar f;
    foo::bar g = foo::bar::A;

    buzz::bar x;
    buzz::bar y = buzz::bar::A;
    buzz::bar z = foo::bar::A;
}

Приведенный выше код успешно компилируется: http://coliru.stacked -crooked.com / a / 2119348acb75d270 .

1 голос
/ 20 июля 2010

Если вам действительно нужно это сделать, попробуйте using namespace foo; вместо using foo::bar;. Однако гораздо удобнее инкапсулировать перечисление в классе или другом пространстве имен.

...