2012-01-02 10 views
18

En mi clase I definida una enumeración de esta manera:usando enumeración dice conversión no válido de 'int' a 'tipo'

class myClass 
{ 
public: 
    enum access { 
     forL, 
     forM, 
     forA 
    }; 
    typedef access AccessType; 
    AccessType aType; 
}; 

Más adelante en definido un objeto como éste:

myClass ob; 
ob->aType = 0; 

Sin embargo, me obtienes este error:

 
error: invalid conversion from 'int' to 'myClass::AccessType {aka myClass::access}' [-fpermissive] 

Do not enum fields map to integers?

+0

Posible duplicado: [Transmitir int a Enum en C#] (http: // stackoverflow.com/questions/29482/cast-int-to-enum-in-c-sharp) – danihp

Respuesta

16

No, se almacenan como enteros, pero son tipos distintos (por ejemplo, puede incluso sobrecargar en función del tipo de enumeración). Debe convertir explícitamente:

myClass ob; 
ob->aType = (myClass::AccessType)0; 

o cada vez mejor escribir el correspondiente valor con nombre de la enumeración:

myClass ob; 
ob->aType = myClass::forL; 

O tal vez, si desea utilizar la enumeración simplemente como un conjunto de constantes enteras, cambiar la tipo del campo:

class myClass 
{ 
public: 
    enum { 
     forL, 
     forM, 
     forA 
    }; 
    int aType; // just stores numbers 
}; 

La conversión de enum a int es implícita.

+0

el objeto se crea en otro archivo. Por lo tanto, no reconoce 'forL'. – mahmood

+0

@mahmood: Ups, debes calificarlo con 'myClass ::'. – ybungalobill

+0

Escribí 'ob-> aType = myClass :: access :: forL;' pero dice 'myClass :: access' no es una clase o espacio de nombres – mahmood

8

Los miembros de la enumeración están respaldados por valores enteros, pero no hay implícita conversión de un entero a un tipo de enumeración. Es necesario utilizar una conversión explícita si realmente desea escribir así:

ob->aType = static_cast<myClass::access>(0); 
+0

¿Es esta una solución portátil (me refiero a las advertencias del compilador en el futuro)? – mahmood

+2

Siempre que el entero especificado esté en el rango válido de la enumeración, cualquier compilador que cumpla con los estándares debería permitir esto según 7.2.10 de la especificación de C++: "Una expresión de tipo aritmético o de enumeración se puede convertir a un tipo de enumeración explícitamente . El valor no cambia si está en el rango de valores de enumeración del tipo de enumeración, de lo contrario, el valor de enumeración resultante no está especificado. " – bobbymcr

2

No se puede hacer una conversión implícita de int -> enumeración, ya que en tiempo de compilación no hay manera de saber que el el yeso es válido.

Usted puede hacer implícita arroja a la inversa, por lo que podría (si quisiera) hacer:

int foo = forL; 
0

sólo tenía misma edición. tengo que inicializar un objeto a partir de lo que he leído en un archivo xml y, de seguro, no tengo control sobre lo que podría suceder con ese archivo.

constructor tiene una enumeración como argumento:

enum status_t { NOT_STARTED, STARTED, DONE }; 
MyObject::MyObject(int id, status_t status) : m_id(id), m_status(status){} 

Así que cuando análisis del XML tengo que echarlo. Preferí manejar el reparto en el constructor para que las otras clases no tengan que saber cuáles son las enumeraciones válidas.

MyObject::MyObject(int id, int status) : m_id(id){ 
    m_status = status_t(status); 
} 

Pero no hay manera de estar seguro de que el valor proveniente de xml estará en el rango correcto.

Aquí está la solución Vine con:

MyObject::MyObject(int id, int status) : m_id(id){ 
    switch(status){ 
     case NOT_STARTED: 
     case STARTED: 
     case DONE: 
      m_status=status_t(status); 
      break; 
     default: 
      m_status=NOT_STARTED; 
      break; 
    } 
} 

Esta es una opción de implementación, para forzar un valor por defecto en el caso de los datos no consistentes. Uno podría preferir tirar una excepción, en mi caso lo hará de esta manera.

Cuestiones relacionadas