¿Cómo convertir int a enum en C ++?


222

¿Cómo convierto un int a una enumeración en C ++?

Por ejemplo:

enum Test
{
    A, B
};

int a = 1;

¿Cómo convierto aa escribir Test::A?


1
link Tenga en cuenta que no importa si int coincide con una de las constantes del tipo enum; La conversión de tipo es siempre ilegal.
Iwaz

3
Creo que si desea convertir a Test :: A, el valor de int atendrá que ser 0, porque Test :: A tiene un valor implícito de 0 y Test :: B tiene un valor implícito de 1. A menos que el hecho de emitir específicamente para Test :: A está más
allá

Respuestas:


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

21
auto val = static_cast <prueba> (i); // C ++ 11
Mitch

3
@ Mitch, ¿qué obtengo por usar autoen este caso? ¿Hay alguna mejora en el rendimiento?
Frederico Pantuzza

2
Sin mejoras de rendimiento. El compilador solo deduce el tipo automáticamente si especifica con "auto". Si decide cambiar su nombre de enumeración en el futuro, modificará menos su código ya que el compilador deducirá automáticamente el nombre de tipo correcto.
Aydin Özcan

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

10
MSDN: el operador static_cast puede convertir explícitamente un valor integral en un tipo de enumeración. Si el valor del tipo integral no se encuentra dentro del rango de valores de enumeración, el valor de enumeración resultante no está definido.
Kirill Kobelev

1
@KirillKobelev si el valor integral puede ser representado por el tipo subyacente de la enumeración, entonces la enumeración resultante debe tener ese valor. De lo contrario, el valor enum producido será el valor resultante de convertir la expresión al tipo subyacente de la enumeración. Si VC ++ hace algo diferente, entonces creo que no es conforme.
bames53

2
qué debe hacer un compilador conforme, si enum tiene valores {1,3,5} y el código intenta hacer <static_cast> del valor de 2. ¿Cómo diferirá eso del C-cast?
Kirill Kobelev

66
@KirillKobelev No estoy usando un static_cast porque hace algo diferente de un molde de estilo C, estoy usando static_cast porque los moldes de C ++ son estilísticamente preferibles a los moldes de C.
bames53

44
@KirillKobelev " si la enumeración tiene valores {1,3,5} " No. El tipo de enumeración no puede limitarse solo a estos 3 valores posibles: {1,3,5} son los enumeradores (denominados valores de enumeración), no la enumeración en sí . Si 1,3,5 son posibles valores de enumeración , entonces también lo es 2.
curiousguy

25

Tu codigo

enum Test
{
    A, B
}

int a = 1;

Solución

Test castEnum = static_cast<Test>(a);

45
Es una buena idea usar el modelo más restrictivo posible y evitar los modelos de estilo C por completo, para darle al compilador la mejor oportunidad de detectar errores. static_castSería un mejor elenco aquí.
Mike Seymour

44
@ Mike Seymour, el problema es que el reparto estático no tiene ninguna diferencia con el reparto C en este caso. ¿Cómo y qué error puede detectar?
Kirill Kobelev

77
@KirillKobelev: El problema es que un reparto de estilo C no es explícito. Puede ser igual a a static_cast, pero bien podría ser const_castao incluso peor, areinterpret_cast o incluso una combinación de ellas. Incluso si sabe ahora en qué se degradará, suponga que cambia aa otro tipo más adelante, podría muy bien ser el tipo de cambios de lanzamiento sin siquiera recibir una advertencia, no quiere eso.
KillianDS

44
@KillianDS " supongamos que cambia un a otro tipo más adelante " ¿qué tipo?
curioso

2
Sí, ya sea esos o un elenco implícito si está disponible. Es mucho más claro cuál es la intención del elenco.
KillianDS

8

Escupiendo la pregunta de cierre, "¿cómo convierto un a tipo Test::A" en lugar de ser rígido sobre el requisito de tener un elenco allí, y respondiendo varios años tarde, esto parece ser una pregunta popular que nadie más parece haber mencionado la alternativa , según el estándar C ++ 11:

5.2.9 Fundición estática

... una expresión ese puede convertir explícitamente a un tipo T usando a static_castde la forma static_cast<T>(e)si la declaración T t(e);está bien formada, para alguna variable temporal inventada t(8.5). El efecto de una conversión tan explícita es el mismo que realizar la declaración e inicialización y luego usar la variable temporal como resultado de la conversión.

Por lo tanto, directamente usando el formulario t(e) también funcionará, y es posible que lo prefiera por pulcritud:

auto result = Test(a);

esta solución funcionó en caso de que la opción del compilador bloqueara static_cast <> (verificación semántica) No es que tenga sentido para mí, pero aún así ordenado.
Sr. Buisson el

1

Test castEnum = static_cast<Test>(a-1);lanzará un a A. Si no quieres la subestructura 1, puedes redefinir enum:

enum Test
{
    A:1, B
};

En este caso, 'Test castEnum = static_cast (a);' podría usarse para lanzar un a A.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.