2008-09-16 13 views
17

¿Hay alguna forma de tener una enumeración de 64 bits en C++? Mientras refactorizaba algunos códigos, encontré un montón de #defines que sería mejor como una enumeración, pero al tener más de 32 bits causaba errores en el compilador.64 bit enum en C++?

Por alguna razón por la que cree que los siguientes podría funcionar:

enum MY_ENUM : unsigned __int64 
{ 
    LARGE_VALUE = 0x1000000000000000, 
}; 
+0

¿Existe una razón para preferir '' __int64' sin firmar sobre uint64_t'? Creo que 'uint64_t' se define para casi todas las plataformas relevantes, pero' unsigned __int64' suena como una definición específica de plataforma (hardware, compilador o incluso biblioteca). – Johan

Respuesta

14

No creo que eso sea posible con C++ 98. La representación subyacente de las enumeraciones depende del compilador. En ese caso, es mejor usar:

const __int64 LARGE_VALUE = 0x1000000000000000L; 

A partir de C++ 11, es posible utilizar las clases de enumeración para especificar el tipo de base de la enumeración:

enum class MY_ENUM : unsigned __int64 { 
    LARGE_VALUE = 0x1000000000000000ULL 
}; 

Además enumeración las clases introducen un nuevo alcance de nombre. Entonces, en lugar de referirse a LARGE_VALUE, debe hacer referencia al MY_ENUM::LARGE_VALUE.

+0

Esto es a lo que recurrí al final, pero tenía curiosidad sobre si las enumeraciones de 64 bits son posibles, incluso con una extensión específica del compilador. – Rob

0

una enumeración en C++ puede ser cualquier tipo integral. Puedes, por ejemplo, tener una enumeración de caracteres. IE:

enum MY_ENUM 
{ 
    CHAR_VALUE = 'c', 
}; 

Me asumir esto incluye __int64. Intentar apenas

enum MY_ENUM 
{ 
    LARGE_VALUE = 0x1000000000000000, 
}; 

Según mis comentarista, sixlettervariables, en C el tipo base será siempre un int, mientras que en C++ es el tipo de base es lo suficientemente grande como para adaptarse a la mayor valor incluido. Por lo tanto, ambas enumeraciones anteriores deberían funcionar.

+1

@Doug T .: mientras que ANSI C dicta que las enumeraciones son del tamaño del tipo de datos 'int', ISO C++ dicta que las enumeraciones son del tamaño al menos tan grande como sea necesario para representar todos los valores. – user7116

1

Puesto que usted está trabajando en C++, otra alternativa podría ser

const __int64 LARVE_VALUE = ... 

Esto se puede especificar en un archivo H.

+0

Intenté 9 caracteres con el primer intento. – Behrooz

2

Si el compilador no admite enumeraciones de 64 bits mediante indicadores de compilación o cualquier otro medio, creo que no hay solución para este.

Se podría crear algo así como en su muestra algo como:

namespace MyNamespace { 
const uint64 LARGE_VALUE = 0x1000000000000000; 
}; 

y usarlo como una enumeración usando

MyNamespace::LARGE_VALUE 

o

using MyNamespace; 
.... 
val = LARGE_VALUE; 
+1

Y seguridad de tipo suelto, sin embargo. –

+0

Desafortunadamente sí – INS

+2

La velocidad de nuestra conversación me recuerda al ajedrez de correspondencia: D –

1

su snipplet de código es no estándar de C++:

enumeración MY_ENUM: __int64 sin firmar

no tiene sentido.

uso const __int64 lugar, como sugiere Torlack

+0

lo ha visto prolly en otro lenguaje de llaves (por ejemplo, C# lo admite) o en el próximo estándar de C++, donde esto será permitido. –

17

C++ 11 soporta, con esta sintaxis:

enum class Enum2 : __int64 {Val1, Val2, val3}; 
+0

Estaba cerca entonces. Debo leer acerca de la sintaxis ': type' en alguna parte. – Rob

+2

tenga en cuenta que 'clase' sigue siendo opcional. Si quieres enum de estilo antiguo, pero con un tipo personalizado, también puedes usar 'enum moo: long long {...}' –

4

Las respuestas pasajes concernientes a la __int64 pierda el problema. La enumeración es válida en todos los compiladores C++ que tienen un tipo integral verdadero de 64 bits, es decir, cualquier compilador C++ 11, o compiladores C++ 03 con extensiones apropiadas. Las extensiones de C++ 03 como __int64 funcionan de forma diferente en los compiladores, incluida su idoneidad como tipo de base para las enumeraciones.

0

En MSVC++ se puede hacer esto:

enumeración MYLONGLONGENUM: __ Int64 {BIG_KEY = 0x3034303232303330, ...};

+2

para usar mejor int64-max que una conjetura mágica. –

5

El borrador actual de la llamada C++0x, es n3092 dice en 7.2 declaraciones de enumeración, párrafo 6:

Es definido por la implementación, que se utiliza tipo integral como el tipo subyacente 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 int sin signo.

el mismo párrafo se dice:

Si ningún tipo integral puede representar todos los valores empadronador, está mal formada, la enumeración .

Mi interpretación de la parte a menos que el valor de un enumerador no puede caber en un int o unsigned int es que es perfectamente válido y seguro para inicializar enumerador con el valor entero de 64 bits, siempre y cuando no hay 64- tipo entero de bit proporcionado en una implementación particular de C++.

Por ejemplo:

enum MyEnum 
{ 
    Undefined = 0xffffffffffffffffULL 
}; 
+3

Si no quieres contar tus F, simplemente puedes hacer 'Undefined = ~ 0x0ULL' –

1

tipo Enum se determina normalmente por el tipo de datos de la primera inicializador enum. Si el valor excede el rango para ese tipo de datos integrales, el compilador de C++ se asegurará de que se ajuste usando un tipo de datos integral más grande. Si el compilador encuentra que no pertenece a ninguno de los tipos de datos integrales, el compilador emitirá el error. Ref: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf
Editar: Sin embargo, esto es puramente dependía de la arquitectura de la máquina