Возможно ли использование «using enum» в С++ 20 в классах?

В этом ответе упоминалось, что в готовящемся стандарте C++20 можно использовать оператор using для enum class и импортировать поля enum в локальное пространство имен.

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

class Foo {
    enum class Color
    {
        red, 
        blue
    };
    using enum Color;
};

int main()
{
    Foo::Color c = Foo::red;
}

Или мне все еще нужно указать полное пространство имен?:

    Foo::Color c = Foo::Color::red;

Пробовал на wandbox.org, но, похоже, ни gcc, ни clang пока не знают про using enum.


person the_summer    schedule 12.09.2019    source источник
comment
Обратите внимание, что C++20 еще не ратифицирован, поэтому неудивительно, что компиляторы не имеют полной поддержки.   -  person NathanOliver    schedule 12.09.2019
comment
@ Натан Оливер, да, я знаю. Это не было задумано как критика. Просто наблюдение.   -  person the_summer    schedule 12.09.2019


Ответы (1)


Да, Foo::Red будет работать нормально. using enum E ведет себя как из [enum.udecl]:

объявление-использования-перечисления вводит имена перечислителей именованного перечисления, как будто с помощью объявления-использования для каждого перечислителя.

И в стандарте есть пример именно этого случая:

[Примечание: объявление-использования-перечисления в области класса добавляет перечислители именованного перечисления в качестве членов области. Это означает, что они доступны для поиска членов. [ Пример:

enum class fruit { orange, apple };
struct S {
  using enum fruit;             // OK, introduces orange and apple into S
};
void f() {
  S s;
  s.orange;                     // OK, names fruit​::​orange
  S::orange;                    // OK, names fruit​::​orange
}

— конец примера ] — конец примечания ]


Обратите внимание, однако, что есть некоторые разногласия по поводу конкретного написания этой функции. enum E — это то, что известно как уточненный спецификатор типа (очень похоже на class C или struct S). Как правило, уточненные спецификаторы типов ведут себя точно так же, как и их базовые версии. Уточнение просто предназначено для устранения неоднозначности, а вам редко нужно устранять неоднозначность, поэтому вы не увидите его очень часто. Однако в данном конкретном случае using enum E и using E на самом деле означают совершенно разные и совершенно не связанные друг с другом вещи. Так что имейте в виду, что есть шанс, что эта функция может еще не появиться в C++20, несмотря на то, что в настоящее время она находится в рабочем проекте и даже опубликована на компакт-диске. Таким образом, маловероятно, что компиляторы будут реализовывать эту функцию до тех пор, пока они не будут уверены, что это необходимо реализовать (в C++20 точно не хватает работы для авторов компиляторов...)

person Barry    schedule 12.09.2019
comment
Это даже лучше, чем я себе представлял. Импорт классов enum из-за пределов класса. Это должно значительно упростить переход к классам enum, чтобы большинство пользователей этого не заметили. - person the_summer; 12.09.2019
comment
Интересно, что выбранное решение проблемы сложного спецификатора типа состояло в том, чтобы определить using enum просто как ключевое слово using, за которым следует спецификатор сложного типа enum, тем самым определяя using enum E как частный случай using E, а не как не связанный с using E. - person Justin Time - Reinstate Monica; 01.02.2021
comment
@JustinTime-ReinstateMonica Я не понимаю тебя? - person Barry; 02.02.2021
comment
Просто комментирую, как они решили проблему, когда using enum E и using E означают разные вещи, @Barry. - person Justin Time - Reinstate Monica; 02.02.2021