2012-03-24 5 views
16

Si tengo una enumeración de C++:¿Cómo cambiar el tipo de entero utilizado por una enumeración (C++)?

enum Foo 
{ 
    Bar, 
    Baz, 
    Bork, 
}; 

¿Cómo le digo al compilador que use un uint16_t para almacenar en realidad el valor de la enumeración?

EDITAR: ¿GCC admite esta característica en su implementación de C++ 11?

+1

@YochaiTimmer, el estándar cambió y el tema en el enlace no dice sobre 'enum class' – Lol4t0

+0

@YochaiTimmer: en absoluto. Quiero saber si puedo cambiar enum para almacenar internamente sus valores con un 'uint16_t', no si es del mismo tamaño que' int'. – Linuxios

Respuesta

23

No puede hacer esto en C++ 98/03 . C++ 11 no le permiten hacerlo, y sin enum class la forma en todo el mundo parece tener le dice:

enum EnumType : uint16_t 
{ 
    Bar, 
    Baz, 
    Bork, 
}; 

Una vez más, usted no tiene que utilizar enum class. No es una mala idea, pero usted no tiene tiene a.


¿Apoya GCC esta función en la implementación de C++ 11?

Which version of GCC? Parece que GCC 4.4 añade esta funcionalidad, pero es probable que debe mirar a las versiones más recientes, sólo por el bien de la estabilidad.

+0

Me lo estaba preguntando. La única diferencia es que 'enum class' crea un nuevo ámbito, mientras que' enum' no. – chris

+3

@chris: No, hay varias diferencias entre 'enum class' y' enum'. Ambos crean ámbitos (se puede acceder a la 'Barra' anterior con 'EnumType :: Barra'), pero solo la 'versión' de clase * lo obliga * a usar la enumeración de ámbito. Además, las variables 'enum class' no * implícitamente * convierten enteros al tipo de enumeración. Por lo tanto, debe pasar un enumerador real del tipo correcto o debe realizar un lanzamiento explícito. Esto agrega un * lote * más tipo de seguridad. –

+0

Oh, tengo mi punto de otra pregunta en SO: http://stackoverflow.com/questions/441552/scope-resolution-operator-on-enums-a-compiler-specific-extension En cuanto a su segundo punto, simplemente nunca escuché sobre eso. Gracias por el conocimiento gratuito :) – chris

5

Con c++11 ahora tiene enum class, que le permite configurar el tipo subyacente de forma explícita:

enum class Foo: uint16_t 
{ 
    Bar, 
    Baz, 
    Bork, 
}; 
13

En C++ 11, se puede hacer eso:

enum class Foo : uint16_t 
{ 
    Bar, 
    Baz, 
    Bork, 
}; 

Más tarde, puede también know the underlying type of the enum como:

#include <type_traits> 

std::underlying_type<Foo>::type v = 10; //v is uint16_t 
+3

+1 para agregar la consulta 'underlying_type'. –

5

Con la pre-C++ 2011 se puede obligar a un mínimo de almacenamiento mediante el uso de una gama adecuada de valores:

enum foo { 
    v0 = 0, 
    vmax = 32767 
}; 

Creo que el compilador es libre de elegir entre un signo o un tipo entero sin signo como el tipo subyacente. El rango anterior exige que la representación use al menos short como entero subyacente. Hacerlo aún más grande puede hacer que use long en su lugar. Por supuesto, esto solo obliga a un rango mínimo y el compilador es libre de elegir un rango más grande. Además, con la definición anterior, no puede desviarse del rango [0, 32767]: si realmente necesita un rango de 16 bits (al menos), debe usar los valores correspondientes).

+1

En realidad, también existe una restricción en el tamaño del tipo subyacente. [dcl.enum]/6 precisas: excepto que el tipo subyacente no debe ser mayor que 'int' a menos que el valor de un enumerador no pueda caber en un' int' o 'unsigned int'. –

Cuestiones relacionadas