c++ - пример - yield c#



В C++ 14, в какой области объявляются перечислители с незаданной областью для объявленных перечислений? (1)

C ++ 14 (точнее, N4296) говорит относительно перечислений в 7.2: 11:

Каждое имя-перечисления и каждый перечислитель с незаданной областью объявляются в области, которая непосредственно содержит спецификатор-перечисления.

Что произойдет, если пространство имен N содержит непрозрачное объявление enum для перечисления E, а затем перечисление полностью объявлено из глобального пространства имен? Должны ли мы найти его перечислители в глобальном пространстве имен или в пространстве имен N?

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

namespace N { enum E : int; }
enum N::E : int {A,B};

namespace N {
    int foo() {
        return int(::N::B);
    }
}

int bar() {
    //return int(::A);
    return int(A);
}

Первая строка в bar закомментирована, потому что clang++ -std=c++14 говорит:

нет члена с именем «A» в глобальном пространстве имен; Вы имели в виду просто «А»?

Gcc не может скомпилировать обе строки в bar (). Таким образом, и gcc, и clang объявляют перечисления в пространстве имен N

Итак, мои вопросы:

  1. Какова область, которая немедленно содержит спецификатор enum? (Мне кажется, это область глобального пространства имен).
  2. Должны ли перечислители A , B быть определены в глобальном пространстве имен?
  3. В функции bar почему ::A не ссылается на перечислитель, а простой A делает?
  4. Почему выражение ::N::B в функции N::foo обозначает перечислитель?

РЕДАКТИРОВАТЬ 1: исходное объявление было enum ::N::E : int {A,B}; , но gcc не смог разобрать его ( отчет об ошибке ), поэтому я удалил начальные двоеточия для использования enum N::E : int {A,B};

РЕДАКТИРОВАТЬ 2: поведение Clang является bug


Перечисление E объявлено в пространстве имен N, даже если его определение установлено в глобальном пространстве имен. Как таковой, он может быть доступен только в объеме N.

Функция бара должна быть определена как:

int bar() {
    return int(N::A);
    //SAME AS --> return int(::N::A);
}




language-lawyer