enum class (C++/CLI и C++/CX)
Объявляет перечисление в области видимости пространства имен, которое является определяемым пользователем типом, состоящим из ряда именованных констант, называемых перечислителями.
Все среды выполнения
Замечания
C++/CX и C++/CLI поддерживают открытый класс перечисления и закрытый класс перечисления, которые схожи со стандартным классом перечисления C++, но с добавлением спецификатора доступа. В /CLR тип класса перечисления C++11 разрешен, но будет создавать предупреждение C4472, предназначенное для того, чтобы убедиться, что вам действительно требуется тип перечисления стандарта ISO, а не типы C++/CX или C++/CLI. Дополнительные сведения о ключевом слове ISO Standard C++ enum
см. в перечислениях.
Среда выполнения Windows
Синтаксис
access
enum class
enumeration-identifier
[:underlying-type] { enumerator-list } [var];
accessenum structenumeration-identifier[:underlying-type] { enumerator-list } [var];
Параметры
access
Уровень доступа перечисления, который может иметь значение public
или private
.
enumeration-identifier
Имя перечисления.
underlying-type
(Необязательно) Базовый тип перечисления.
(Необязательно. только среда выполнения Windows) Базовый тип перечисления, который может быть bool
, int16
char16
char
, , , uint16
, int
, uint32
int64
или .uint64
enumerator-list
Разделенный запятыми список имен перечислителей.
Значение каждого перечислителя — константное выражение, которое или определяется неявно компилятором, или явно нотацией enumerator=
constant-expression. По умолчанию значение первого перечислителя ноль, если он определен неявно. Значение каждого следующего неявно определенного перечислителя — значение предыдущего перечислителя + 1.
var
(Необязательно) Имя переменной типа перечисления.
Замечания
Дополнительные сведения и примеры см. в разделе Перечисления.
Обратите внимание, что компилятор выводит сообщения об ошибках, если константное выражение, задающее значение перечислителя, не может быть представлено underlying-type. Однако компилятор не сообщает об ошибке для значения, недопустимого для базового типа. Например:
Если базовый тип является числовым, а перечислитель задает максимальное значение этого типа , значение следующего неявно определенного перечисления невозможно представить.
Если underlying-type является
bool
и более двух перечислителей определены неявно, то нельзя представить перечислители после первых двух.Если underlying-type является
char16
и значение перечисления в диапазоне от 0xD800 до 0xDFFF, то значение можно представить. Однако логически значение неверно, так как оно представляет половину пары символов-заместителей Юникода и не должно отображаться в изоляции.
Требования
Параметр компилятора: /ZW
Среда CLR
Синтаксис
access
enum class
name [:type] { enumerator-list } var;
accessenum structname [:type] { enumerator-list } var;
Параметры
access
Уровень доступа перечисления. Может быть либо public
, либо private
.
enumerator-list
Разделенный запятыми список идентификаторов (перечислителей) в перечислении.
name
Имя перечисления. Анонимные управляемые перечисления не допускаются.
type
(Необязательно) Базовый тип identifiers. Это может быть любой скалярный тип, например подписанные или неподписанные 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) не вводятся в область, в которой определяется перечисление; все ссылки на перечислители должны быть полными (имя::
идентификатор). По этой причине нельзя определить анонимное управляемое перечисление.
Перечислители стандартного перечисления строго вводятся во внешнюю область. То есть, если есть другой символ с таким же именем, как у перечислителя во внешней области видимости, компилятор выдаст ошибку.
В Visual Studio 2002 и Visual Studio 2003 перечислители были нестрого вводимыми (видимыми во внешней области, если не было другого идентификатора с таким же именем).
Если определен стандартный перечисление C++ (без class
или struct
), компиляция с /clr
помощью этого перечисления приведет к компиляции в виде управляемой перечисления. Перечисление по-прежнему имеет семантику неуправляемого перечисления. Обратите внимание, что компилятор вводит атрибут Microsoft::VisualC::NativeEnumAttribute
для определения намерения программиста сделать перечисление собственным. Другие компиляторы просто увидят стандартное перечисление как управляемое перечисление.
Именованное стандартное перечисление, скомпилированное с параметром /clr
, будет видимо в сборке как управляемое перечисление и может использоваться любым другим управляемым компилятором. Однако безымянное стандартное перечисление не будет видимо из сборки.
В Visual Studio 2002 и Visual Studio 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
Примеры
// 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);
}
no automatic conversion to int: b
convert to int: 1
1
1