error reinterpret_cast para enumeración

¿Por qué no puedo usar el operador reinterpret_cast para tal lanzamiento?

enum Foo { bar, baz };

void foo(Foo)
{
}

int main()
{
   // foo(0); // error: invalid conversion from 'int' to 'Foo'
   // foo(reinterpret_cast<Foo>(0)); // error: invalid cast from type 'int' to type 'Foo'
   foo(static_cast<Foo>(0)); 
   foo((Foo)0);
}

preguntado el 01 de septiembre de 12 a las 15:09

static_cast es la operación correcta aquí. -

¿Por qué sería válido? ¿Para qué crees que sirve reinterpret_cast? -

Creo que reinterpret_cast se puede usar para todo tipo de conversiones, porque fuerza cualquier conversión de tipo a otro tipo con todos los efectos secundarios de esta conversión. -

2 Respuestas

Creo que reinterpret_cast se puede usar para todos los tipos de conversiones, porque fuerza cualquier conversión de tipo a otro tipo con todos los efectos secundarios de esta conversión.

Ese es un error común. Conversiones que se pueden realizar con reinterpret_cast se enumeran explícitamente en 5.2.10 de la norma. int-A-enum y enum-A-int las conversiones no están en la lista:

  • Puntero al tipo integral, siempre que el entero sea lo suficientemente grande para contenerlo
  • nullptr_t a entero
  • tipo integral o enum al puntero
  • puntero de función a otro puntero de función de diferente tipo
  • puntero de objeto a otro puntero de objeto de diferente tipo
  • nullptr_t a otro tipo de puntero
  • puntero a miembro de T1 a un puntero a miembro diferente de T2 en los casos en que ambos T1 y T2 son objetos o funciones

reinterpret_cast se usa típicamente para decirle al compilador: Oye, sé que piensas que esta región de la memoria es una T, pero me gustaría que lo interpretes como un U (dónde T y U son tipos no relacionados).

También vale la pena señalar que reinterpret_cast puede tener efectos en los bits:

5.2.10.3

[ Nota: El mapeo realizado por reinterpret_cast podría, o no, producir una representación diferente del valor original. - nota final]

El elenco de estilo C siempre funciona, porque incluía static_cast en sus intentos.

Respondido el 01 de Septiembre de 12 a las 16:09

Debido a que el tipo subyacente de enumeración regular es int, No hay nada que reinterpretar. La conversión estática es la conversión adecuada para este caso.

Respondido el 01 de Septiembre de 12 a las 15:09

@Rost eso no es cierto. El estándar garantiza que el tipo subyacente de un emum es un tipo integral, pero no necesariamente un int. - dibujó dormann

@tenfour Bueno, se agregó en C++ 11. No se el motivo. ¿Posiblemente para permitir algunos trucos de plantilla? - Rost

Si "no hay nada que reinterpretar" tuviera algo que ver con la corrección, entonces esto fallaría: int x = 0; int* p = reinterpret_cast<int*>(&x); - travis gockel

@TravisGockel Incluso reinterpret_cast<int>(x) esta permitido. ¿Y qué? solo significa que reinterpret_cast en realidad no reinterpretar en algunos casos. Entonces, ¿podríamos nombrarlo? maybe_reinterpret_cast? ;-)- Rost

La razón enum-A-int no se puede hacer a través reinterpret_cast no tiene nada que ver con el tipo subyacente de la enum. Si era enum Foo : uint64_t { bar, baz }, reinterpret_cast<int> todavía no estaría permitido. - travis gockel

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.