Як віддати int до перерахунку в C ++?


222

Як я можу подати int до enum у C ++?

Наприклад:

enum Test
{
    A, B
};

int a = 1;

Як перетворити aна тип Test::A?


1
посилання Зауважте, що не має значення, чи відповідає int одній із констант типу enum; перетворення типів завжди незаконне.
Іваз

3
Я вважаю, що якщо ви хочете перейти на Test :: Значення int aмає бути 0, тому що Test :: A має неявне значення 0, а Test :: B має неявне значення 1. Якщо тільки факт кастингу спеціально для Тесту :: A, окрім пункту ...
JohnRDOrazio

Відповіді:


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

21
auto val = static_cast <Тест> (i); // C ++ 11
Мітч

3
@Mitch Що я можу використовувати autoв цьому випадку? Чи є якісь покращення продуктивності?
Фредеріко Пантуцца

2
Не покращено продуктивність. Компілятор просто виводить тип автоматично, якщо ви вказали з "auto". Якщо ви вирішите змінити своє ім'я enum у майбутньому, ви будете змінювати свій код менше, оскільки компілятор автоматично виведе правильне ім'я типу.
Айдін

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

10
MSDN: Оператор static_cast може явно перетворити інтегральне значення в тип перерахунку. Якщо значення інтегрального типу не потрапляє в діапазон значень перерахування, отримане значення перерахування не визначається.
Кирило Кобелєв

1
@KirillKobelev, якщо інтегральне значення може бути представлене базовим типом enum, то результуюча enum повинна мати це значення. В іншому випадку отримане значення перерахунку буде будь-яким значенням, що є результатом перетворення виразу в базовий тип. Якщо VC ++ робить щось інше, то я думаю, що це невідповідно.
bames53

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

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

4
@KirillKobelev " якщо 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
@Mike Seymour, проблема полягає в тому, що статичний амплуа не має відмінностей від C-лиття в цьому випадку. Як і яку помилку він може виявити ???
Кирило Кобелєв

7
@KirillKobelev: Проблема в тому, що акторський склад у стилі C не є явним. Він може дорівнювати a static_cast, але може бути const_castі навіть гіршим, reinterpret_castабо навіть комбінацією цих. Навіть якщо ви тепер знаєте, на що воно погіршиться, припустимо, ви перейдете aна інший тип пізніше, це цілком може бути типом змін кастингу, без того, як ви коли-небудь отримаєте стільки, скільки попередження, цього не хочете.
KillianDS

4
@KillianDS " припустимо, ви пізніше перейдете на інший тип ", який тип?
curiousguy

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);буде відкидати А. Якщо ви не хочете substruct 1, ви можете перевизначити enum:

enum Test
{
    A:1, B
};

У цьому випадку `Test castEnum = static_cast (a); ' може бути використаний для того, щоб подати на А.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.