Pregunta

He estado tratando de leer un poco del estándar de C++ para averiguar cómo la enumeración de trabajo.En realidad hay mucho más allí de lo que se pensaba originalmente.

Para un ámbito de la enumeración, es claro que el tipo subyacente es int a menos que se especifique lo contrario con una enumeración de base de la cláusula (puede ser de cualquier tipo integral).

enum class color { red, green, blue};  // these are int

Para el ámbito enumeraciones, parece que el tipo subyacente puede ser cualquier tipo integral que va a funcionar y que no va a ser más grande que un int, a menos que sea necesario.

enum color { red, green, blue};  // underlying type may vary

Desde el tipo subyacente de ámbito enumarations no están estandarizados, ¿cuál es la mejor manera de lidiar con serializar instancias de uno?Hasta ahora, he sido convertir a int cuando la escritura, a continuación, registrar en un int y la configuración de mi enum variable en un interruptor al leer, pero parece un poco torpe.Hay una manera mejor?

enum color { red, green, blue };
color c = red;
// to serialize
archive << (int)c;
// to deserialize
int i;
archive >> i;
switch(i) {
  case 0: c = red; break;
  case 1: c = green; break;
  case 2: c = blue; break;
}
¿Fue útil?

Solución

No he leído ninguna materia C ++ 0x así que no podía comentar sobre eso.

En cuanto a la serialización, no es necesario el interruptor al leer la enumeración nuevamente. - simplemente lo echó al tipo de enumeración

Sin embargo, no lo echo al escribir a la corriente. Esto se debe a menudo me gusta escribir un operador << para la enumeración para que pueda coger malos valores se escriben, o entonces puedo decidir que escribir una cadena en lugar.

enum color { red, green, blue };
color c = red;

// to serialize
archive << c;    // Removed cast

// to deserialize
int i;
archive >> i;
c = (color)i;    // Removed switch

Otros consejos

clase enum es una C ++ 0x característica, no está presente en C ++ 03.

  

En estándar C ++, enumeraciones no son de tipo seguro. Ellos son enteros de manera efectiva, incluso cuando los tipos de enumeración son distintos. Esto permite la comparación entre dos valores de enumeración de diferentes tipos de enumeración. La única seguridad que C ++ 03 proporciona es que un número entero o un valor de un tipo enum no convierte implícitamente a otro tipo de enumeración. Además, el tipo integral subyacente, el tamaño del entero, no se puede especificar de forma explícita; es definido por la implementación. Por último, los valores de enumeración están en el ámbito de la ámbito de inclusión. Por lo tanto, no es posible que dos enumeraciones separadas tengan emparejan nombres de los miembros.   C ++ 0x permitirá una clasificación especial de enumeración que no tiene ninguna de estas cuestiones. Esto se expresa mediante la declaración de clase de enumeración

Ejemplos (del artículo de Wikipedia):

enum Enum1;                   //Illegal in C++ and C++0x; no size is explicitly specified.
enum Enum2 : unsigned int;    //Legal in C++0x.
enum class Enum3;             //Legal in C++0x, because enum class declarations have a default type of "int".
enum class Enum4: unsigned int; //Legal C++0x.
enum Enum2 : unsigned short;  //Illegal in C++0x, because Enum2 was previously declared with a different type.

En cuanto a la parte de serialización (que creo que no era parte de la pregunta original), prefiero crear una clase de ayuda que se traduce artículos de enumeración en su cadena equivalente (y viceversa), ya que los nombres son por lo general más estable que el valores enteros que representan, como artículos de enumeración pueden ser (y, a veces son) reordenado sin cambiar el comportamiento de código.

He decidido crear una nueva respuesta, porque mi viejo era tan desordenado. De todos modos sólo quiero decir algo sobre 11 C ++, donde se puede obtener el tipo subyacente de una enumeración utilizando la siguiente:

std::underlying_type_t<E>

Y por el bien de su interés, la idea de resolución de sobrecarga. Pero, por favor utilice nombres para almacenar la enumeración, según lo propuesto por @lothar.

La resolución de sobrecarga se deriva del hecho de que existen una promoción de una enumeración a la primera de int, unsigned int, largo, largo sin signo que puede representar todos los valores de su tipo subyacente. Una conversión a cualquier otro tipo entero está en el puesto más bajo y resolución de sobrecarga no se prefieren.

char (& f(int) )[1];
char (& f(unsigned int) )[2];

char (& f(long) )[3];
char (& f(unsigned long) )[4];

char const* names[] = { 
    "int", "unsigned int", 
    "long", "unsigned long"
};

enum a { A = INT_MIN };
enum b { B = UINT_MAX };
enum c { C = LONG_MIN };
enum d { D = ULONG_MAX };

template<typename T> void print_underlying() {
    std::cout << names[sizeof(f(T()))-1] << std::endl;
}

int main() { 
    print_underlying<a>();
    print_underlying<b>();
    print_underlying<c>();
    print_underlying<d>();
}

Y se imprime este de aquí:

int
unsigned int
int
unsigned int

No es de particular interés a este problema de serialización (ya que el tamaño de los datos serializados no es de anchura constante, y esto puede causar problemas cuando se cambia la enumeración y su tipo subyacente), pero generalmente es interesante para averiguar un tipo de almacenamiento de la totalidad de una enumeración. Saludos!

#include <type_traits>

enum a { bla1, bla2 };
typedef typename std::underlying_type<a>::type underlying_type;

if (std::is_same<underlying_type, int>::value)
  std::cout << "It's an int!" << endl;
else if (std::is_same<underlying_type, unsigned int>::value)
  std::cout << "It's an uint!" << endl;

En cuanto a enum class color:? ¿Es esta C ++ / CLI (C ++) o en el futuro código C ++ 0x

Para la serialización, se puede obtener el tamaño de la enumeración con sizeof(color) saber cuántos bytes a copiar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top