sirve que programas paso para lenguaje ejemplos comandos caracteristicas c++ enums c++11

que - lenguaje c++ ejemplos



Tipo subyacente de una enumeraciĆ³n de C++ en C++ 0x (5)

He estado intentando leer un poco del estándar de C ++ para descubrir cómo funciona la enumeración. De hecho, hay más de lo que originalmente pensé.

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

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

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

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

Dado que el tipo subyacente de enumaraciones sin ámbito no está estandarizado, ¿cuál es la mejor manera de tratar con la serialización de instancias de una? Hasta ahora, he estado convirtiendo a int al escribir, luego serializar en un int y configurar mi variable enum en un interruptor al leer, pero parece un poco torpe. ¿Hay alguna 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; }


Decidí crear una nueva respuesta porque mi viejo era muy desordenado. De todos modos, solo quiero decir algo sobre C ++ 11, donde puede obtener el tipo subyacente de una enumeración usando este:

std::underlying_type_t<E>

Y por el bien del interés, la idea de resolución de sobrecarga. Pero use nombres para almacenar la enumeración, como lo propone @lothar.

La resolución de sobrecarga se deriva del hecho de que existe una promoción de una enumeración a la primera de int, unsigned int, long, unsigned long que puede representar todos los valores de su tipo subyacente. Una conversión a cualquier otro tipo de número entero tiene una clasificación más baja y la resolución de sobrecarga no lo preferirá.

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 esta imprime esta aquí:

int unsigned int int unsigned int

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


En cuanto al enum class color : ¿Es este C ++ / CLI (C ++ .NET) o el código de C ++ 0x futuro?

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


No he leído nada de C ++ 0x, así que no puedo comentar sobre eso.

En cuanto a la serialización, no necesita el interruptor al volver a leer la enumeración; simplemente conviértalo al tipo de enumeración.

Sin embargo, no lanzo al escribir en la corriente. Esto se debe a que a menudo me gusta escribir un operador << para la enumeración, por lo que puedo detectar los valores incorrectos que se escriben, o puedo decidir escribir una cadena en su 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


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

En C ++ estándar, las enumeraciones no son de tipo seguro. Son efectivamente enteros, 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 proporciona C ++ 03 es que un número entero o un valor de un tipo de enumeración no se convierte implícitamente a otro tipo de enumeración. Además, el tipo de integral subyacente, el tamaño del entero, no se puede especificar explícitamente; Es la implementación definida. Por último, los valores de enumeración se incluyen en el ámbito que abarca. Por lo tanto, no es posible que dos enumeraciones separadas tengan nombres de miembros coincidentes. C ++ 0x permitirá una clasificación especial de enumeración que no tiene ninguno de estos problemas. Esto se expresa utilizando la declaración de clase enum.

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 formaba parte de la pregunta original), prefiero crear una clase auxiliar que traduzca los elementos de enumeración a su cadena equivalente (y anterior), ya que los nombres suelen ser más estables que los valores enteros que Representar, ya que los elementos de enumeración pueden ser (y, a veces,) reordenados sin cambiar el comportamiento del código.


#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;