Как привести int к enum в C ++?


222

Как я могу привести int к перечислению в C ++?

Например:

enum Test
{
    A, B
};

int a = 1;

Как мне конвертировать aв тип Test::A?


1
ссылка Обратите внимание, что не имеет значения, соответствует ли int одной из констант типа enum; преобразование типов всегда недопустимо.
Иваз

3
Я считаю, что если вы хотите привести к Test :: A, значение int aдолжно быть 0, потому что Test :: A имеет неявное значение 0, а Test :: B имеет неявное значение 1. Если только не приведен факт приведения специально для тестирования :: А это не
главное

Ответы:


243
int i = 1;
Test val = static_cast<Test>(i);

21
auto val = static_cast <Test> (i); // C ++ 11
Митч

3
@ Митч, что я получу за использование autoв этом случае? Есть ли улучшения производительности?
Фредерико Пантуцца

2
Нет улучшений производительности. Компилятор просто выводит тип автоматически, если вы укажете «auto». Если вы решите изменить свое имя enum в будущем, вы будете меньше изменять свой код, так как компилятор автоматически определит правильное имя типа.
Айдын Озкан

74
Test e = static_cast<Test>(1);

10
MSDN: оператор static_cast может явно преобразовать целое значение в тип перечисления. Если значение целочисленного типа не попадает в диапазон значений перечисления, результирующее значение перечисления не определено.
Кирилл Кобелев

1
@KirillKobelev, если интегральное значение может быть представлено базовым типом перечисления, то итоговое перечисление должно иметь это значение. В противном случае полученное значение перечисления будет любым значением, полученным в результате преобразования выражения в базовый тип перечисления. Если VC ++ делает что-то другое, то я думаю, что это не соответствует.
bames53

2
что должен сделать совместимый компилятор, если enum имеет значения {1,3,5} и код пытается выполнить <static_cast> из значения 2. Как это будет отличаться от C-cast?
Кирилл Кобелев

6
@KirillKobelev Я не использую static_cast, потому что он делает что-то отличное от приведения в стиле C, я использую static_cast, потому что приведение C ++ стилистически предпочтительнее приведений C.
bames53

4
@KirillKobelev " if enum имеет значения {1,3,5} " Нет. Тип перечисления не может быть ограничен только этими 3 возможными значениями: {1,3,5} являются перечислителями (именованными значениями перечисления), а не самим перечислением , Если 1,3,5 являются возможными значениями перечисления , то и 2
любопытно

25

Ваш код

enum Test
{
    A, B
}

int a = 1;

Решение

Test castEnum = static_cast<Test>(a);

45
Хорошей идеей является использование максимально ограниченного приведения, которое вы можете, и вообще избегать приведения в стиле C, чтобы дать компилятору наилучшие шансы на обнаружение ошибок. static_castбыло бы лучше бросить здесь.
Майк Сеймур

4
@ Майк Сеймур, проблема в том, что в этом случае статическое приведение не отличается от C-приведение. Как и какую ошибку он может обнаружить ???
Кирилл Кобелев

7
@KirillKobelev: проблема в том, что приведение в стиле C не является явным. Это может быть равно a static_cast, но это может быть a const_castили даже хуже, a reinterpret_castили даже их комбинация. Даже если вы теперь знаете, в какой степени он будет ухудшаться, предположим, что aпозже вы смените его на другой тип, это вполне может быть типом разыгрывания изменений, когда вы не получите столько предупреждений, сколько вам этого не нужно.
KillianDS

4
@KillianDS " Предположим, вы позже измените тип на " какого типа?
любопытный парень

2
Да, либо те, либо неявное приведение, если доступно. Намного яснее, в чем заключается цель актерского состава.
KillianDS

8

Отвечая на заключительный вопрос, «как мне преобразовать тип в тип Test::A», вместо того, чтобы жестко отнестись к требованию иметь там актерский состав и ответить на несколько лет позже, просто это кажется популярным вопросом, который, кажется, еще никто не упомянул об альтернативе. согласно стандарту C ++ 11:

5.2.9 Статическое приведение

... выражение eможет быть явно преобразовано в тип, T используя static_castформу, static_cast<T>(e)если объявление T t(e);правильно сформировано, для некоторой изобретенной временной переменной t(8.5). Эффект такого явного преобразования такой же, как выполнение объявления и инициализации, а затем использование временной переменной в качестве результата преобразования.

Поэтому прямое использование формы t(e)также будет работать, и вы можете предпочесть ее для аккуратности:

auto result = Test(a);

Это решение работало в случае, если опция компилятора заблокирована static_cast <> (семантическая проверка). Не то чтобы это имело смысл для меня, но все же аккуратно.
Мистер Буиссон,

1

Test castEnum = static_cast<Test>(a-1);приведёт к А. Если вы не хотите подструктуру 1, вы можете переопределить enum:

enum Test
{
    A:1, B
};

В этом случае `Test castEnum = static_cast (a); ' может быть использован для приведения к А.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.