Создание экземпляра класса перечисления С++ 11

Я столкнулся со следующей формой создания экземпляра переменной класса перечисления, и она компилируется без каких-либо предупреждений или ошибок в VS2012:

UINT32 id;
enum class X {apple, pear, orange};
X myX = X(id);

Кроме того, отправка X(id) в качестве аргумента функции, ожидающей параметр типа X, также скомпилирована. Я не уверен, всегда ли результат правильный или это просто странное поведение компилятора.

Однако попытка сделать X myX(id); вместо приведенного выше привела к ошибке компиляции:

ошибка C2440: «инициализация»: невозможно преобразовать «UINT32» в «X». Преобразование в тип перечисления требует явного приведения (static_cast, приведения в стиле C или приведения в стиле функций).

Чтение стандарта С++ 11 не помогло мне понять. Так вот у меня 2 вопроса на эту тему:

  1. Можно ли построить объект класса enum с целочисленным типом в качестве параметра?
  2. Если 1 верно, почему X myX(id) не работает?

person SomeWittyUsername    schedule 18.10.2012    source источник


Ответы (1)


Вы не создаете перечисление с таким синтаксисом. Вместо этого вы используете альтернативный синтаксис явного приведения для приведения от UINT32 к enum class X. Например, можно явно привести тип double к типу int следующим образом:

double p = 0.0;
int f = int(p)

См. эту запись о переполнении стека, чтобы узнать обо всех различных синтаксисе приведения типов, которые вы можете использовать в С++.

Ваш код может быть эквивалентно написан с более распространенным синтаксисом приведения, например:

UINT32 id;
enum class X {apple, pear, orange};
X myX = (X)id;
person cyon    schedule 18.10.2012
comment
Спасибо, я не знал об этом синтаксисе. Но это поднимает другой вопрос: как узнать, приведет ли такой синтаксис к приведению типов или к вызову конструктора класса X? - person SomeWittyUsername; 18.10.2012
comment
@icepack: чтобы вызвать конструктор класса X, X должен сначала быть классом. X — это строго типизированное перечисление, которое не является классом (несмотря на использование слова class в его определении). Когда вы используете classname(stuff), вы всегда будете вызывать конструктор. - person Nicol Bolas; 18.10.2012
comment
Я знаю об этом. Мой последний вопрос носит более общий характер и относится к ситуации, когда X на самом деле является классом. В остальных случаях двусмысленности, естественно, нет. Итак, вы говорите, что этот синтаксис приведения неприменим к классам. - person SomeWittyUsername; 18.10.2012
comment
@ildjarn это неправильно. статическое приведение отличается от первых двух (приведение в стиле c), если вы говорите о неклассовых типах. - person Johannes Schaub - litb; 20.10.2012
comment
(говоря о типах классов, первые два по-прежнему эквивалентны, но вряд ли их можно назвать стилем c). - person Johannes Schaub - litb; 20.10.2012