enum class (расширения компонентов C++)
Объявляет перечисление в области видимости пространства имен, которое является определяемым пользователем типом, состоящим из набора именованных констант, называемых перечислителями.
Все среды выполнения
Примечания
C++/CX и C++/CLI поддерживают public enum class и private enum class, которые похожи на стандартный enum class C++, но с добавлением спецификатора уровня доступа. В /clr тип C++11 enum class разрешен, но будет создаваться предупреждение C4472, которое необходимо, чтобы убедиться, что действительно требуется тип перечисления стандарта ISO, а не тип C ++/CX и C ++/CLI. Дополнительные сведения о ключевом слове C++ enum стандарта ISO см. в разделе Объявления перечислений C++.
Среда выполнения Windows
Синтаксис
access enum class enumeration-identifier [:underlying-type] { enumerator-list } [var];
access enum struct enumeration-identifier [:underlying-type] { enumerator-list } [var];
Параметры
access
Уровень доступа перечисления, который может иметь значение public или private.enumeration-identifier
Имя перечисления.underlying-type
(Необязательно) Базовый тип перечисления.(Необязательно. Только Среда выполнения Windows) Базовый тип перечисления, который может быть bool, char, char16, int16, uint16, int, uint32, int64 или uint64.
enumerator-list
Разделенный запятыми список имен перечислителей.Значение каждого перечислителя — константное выражение, которое или определяется неявно компилятором, или явно нотацией enumerator = constant-expression. По умолчанию значение первого перечислителя ноль, если он определен неявно. Значение каждого следующего неявно определенного перечислителя — значение предыдущего перечислителя + 1.
var
(Необязательно) Имя переменной типа перечисления.
Примечания
Дополнительные сведения и примеры см. в разделе Перечисления.
Обратите внимание, что компилятор выводит сообщения об ошибках, если константное выражение, задающее значение перечислителя, не может быть представлено underlying-type. Однако компилятор не сообщает об ошибке для значения, недопустимого для базового типа. Примеры.
Если underlying-type числовой, и перечислитель определяет максимальное значение для указанного типа, то нельзя представить значение следующего неявно указанного перечисления.
Если underlying-type является bool, и более двух перечислителей определены неявно, то нельзя представить перечислители после первых двух.
Если underlying-type является char16, и значение перечисления в диапазоне от 0xD800 до 0xDFFF, то значение можно представить. Однако логически значение неверно, поскольку оно представляет половину пары символов-заместителей Юникода и не должно отображаться в изоляции.
Требования
Параметр компилятора: /ZW
Среда CLR
Синтаксис
access enum class name [:type] { enumerator-list } var;
access enum struct name [:type] { enumerator-list } var;
Параметры
access
Уровень доступа перечисления. Может быть либо public, либо private.enumerator-list
Разделенный запятыми список идентификаторов (перечислителей) в перечислении.name
Имя перечисления. Анонимные управляемые перечисления не допускаются.type (необязательно)
Базовый тип identifiers. Это может быть любой скалярный тип, например, signed int, unsigned int, short или long. bool или char также допустимы.var (необязательно)
Имя переменной типа перечисления.
Примечания
enum class и enum struct являются эквивалентными объявлениями
Существует два типа перечислений: управляемые (или C++/CX типы) и стандартные.
Управляемые или C ++/CX перечисления могут быть определены следующим образом:
public enum class day {sun, mon };
и семантически эквивалентно:
ref class day {
public:
static const int sun = 0;
static const int mon = 1;
};
Стандартное перечисление может быть определено следующим образом:
enum day2 { sun, mon };
и семантически эквивалентно:
static const int sun = 0;
static const int mon = 1;
Управляемые имена перечислителей (identifiers) не вводятся в область, в которой определяется перечисление; все ссылки на перечислители должны быть полными (name::identifier). По этой причине нельзя определить анонимное управляемое перечисление.
Перечислители стандартного перечисления строго вводятся во внешнюю область. То есть, если есть другой символ с таким же именем, как у перечислителя во внешней области видимости, компилятор сгенерирует ошибку.
В Visual C++ 2002 и Visual C++ 2003 перечислители были слабо вводимыми (видимыми во внешней области, пока не появится другого идентификатора с таким же именем).
Если указано стандартное перечисление C++ (без class или struct), то компилирование с параметром /clr приведет к компиляции перечисления как управляемого. Перечисление по-прежнему имеет семантику неуправляемого перечисления. Обратите внимание, что компилятор вставляет атрибут [Microsoft::VisualC::NativeEnumAttribute], который компилятор Visual C++ распознает для определения намерения программиста сделать перечисление собственным. Другие компиляторы просто увидят стандартное перечисление как управляемое перечисление.
Именованное стандартное перечисление, скомпилированное с параметром /clr, будет видимо в сборке как управляемое перечисление и может использоваться любыми другим управляемым компилятором. Однако безымянное стандартное перечисление не будет видимо из сборки.
В Visual C++ 2002 или Visual C++ 2003 стандартное перечисление использовалось в качестве типа в параметре функции:
// mcppv2_enum.cpp
// compile with: /clr
enum E { a, b };
void f(E) {System::Console::WriteLine("hi");}
int main() {
E myi = b;
f(myi);
}
выдало бы в MSIL для сигнатуры функции следующее:
void f(int32);
Однако в текущих версиях компилятора стандартное перечисление выдается как управляемое перечисление с [NativeEnumAttribute], а в MSIL для сигнатуры функции выдается следующее::
void f(E)
Дополнительные сведения о неуправляемых перечислителях см. в разделе Объявление перечислений C++.
Дополнительные сведения о перечислителях CLR см. в разделе:
Требования
Параметр компилятора: /clr
Примеры
Пример
desc
// mcppv2_enum_2.cpp
// compile with: /clr
// managed enum
public enum class m { a, b };
// standard enum
public enum n { c, d };
// unnamed, standard enum
public enum { e, f } o;
int main()
{
// consume managed enum
m mym = m::b;
System::Console::WriteLine("no automatic conversion to int: {0}", mym);
System::Console::WriteLine("convert to int: {0}", (int)mym);
// consume standard enum
n myn = d;
System::Console::WriteLine(myn);
// consume standard, unnamed enum
o = f;
System::Console::WriteLine(o);
}
Output