Enumerazione a 64 bit in C++?
Domanda
C'è un modo per avere un'enumerazione a 64 bit in C++?Durante il refactoring di parte del codice mi sono imbattuto in un gruppo di #defines che sarebbero migliori come enum, ma essere maggiori di 32 bit causa errori del compilatore.
Per qualche motivo ho pensato che quanto segue potesse funzionare:
enum MY_ENUM : unsigned __int64
{
LARGE_VALUE = 0x1000000000000000,
};
Soluzione
Non penso che sia possibile con C++98.La rappresentazione sottostante delle enumerazioni dipende dal compilatore.In tal caso è meglio utilizzare:
const __int64 LARGE_VALUE = 0x1000000000000000L;
A partire da C++11, è possibile utilizzare le classi enum per specificare il tipo base dell'enum:
enum class MY_ENUM : unsigned __int64 {
LARGE_VALUE = 0x1000000000000000ULL
};
Inoltre le classi enum introducono un nuovo ambito di nome.Quindi invece di fare riferimento a LARGE_VALUE
, faresti riferimento MY_ENUM::LARGE_VALUE
.
Altri suggerimenti
C++11 lo supporta, utilizzando questa sintassi:
enum class Enum2 : __int64 {Val1, Val2, val3};
L'attuale bozza del cosiddetto C++0x, è n3092 dice dentro 7.2 Dichiarazioni di enumerazione, paragrafo 6:
È definito l'implementazione quale tipo integrale viene utilizzato come tipo sottostante, tranne per il fatto che il tipo sottostante non deve essere maggiore di INT a meno che il valore di un enumeratore non possa adattarsi a un INT o INT non firmato.
Lo stesso paragrafo dice anche:
Se nessun tipo integrale può rappresentare tutti i valori di enumeratore, l'enumerazione è mal formale.
La mia interpretazione della parte a meno che il valore di un enumeratore non possa rientrare in un int o unsigned int è che è perfettamente valido e sicuro inizializzare l'enumeratore con un valore intero a 64 bit purché in una particolare implementazione C++ sia fornito un tipo intero a 64 bit.
Per esempio:
enum MyEnum
{
Undefined = 0xffffffffffffffffULL
};
Le risposte si riferiscono a __int64
perdere il problema.L'enum È valido in tutti i compilatori C++ che hanno un vero tipo integrale a 64 bit, vale a direqualsiasi compilatore C++11 o compilatori C++03 con estensioni appropriate.Estensioni a C++03 come __int64
funziona in modo diverso tra i compilatori, inclusa la sua idoneità come tipo base per le enumerazioni.
Se il compilatore non supporta enumerazioni a 64 bit tramite flag di compilazione o qualsiasi altro mezzo, penso che non ci sia soluzione a questo.
Potresti creare qualcosa come nel tuo esempio qualcosa come:
namespace MyNamespace {
const uint64 LARGE_VALUE = 0x1000000000000000;
};
e usarlo proprio come un enum using
MyNamespace::LARGE_VALUE
O
using MyNamespace;
....
val = LARGE_VALUE;
Dato che stai lavorando in C++, un'altra alternativa potrebbe essere
const __int64 LARVE_VALUE = ...
Questo può essere specificato in un file H.
il tuo frammento di codice non è standard C++:
enum MY_ENUM:senza segno __int64
non ha senso.
utilizzare invece const __int64, come suggerisce Torlack
Il tipo di enumerazione è normalmente determinato dal tipo di dati del primo inizializzatore di enumerazione.Se il valore deve superare l'intervallo per quel tipo di dati integrale, il compilatore C++ si assicurerà che si adatti utilizzando un tipo di dati integrale più grande. Se il compilatore rileva che non appartiene a nessuno dei tipi di dati integrali, il compilatore genererà un errore.Rif: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf
Modificare:Tuttavia ciò dipende esclusivamente dall'architettura della macchina
Un'enumerazione in C++ può essere qualsiasi tipo integrale.Puoi, ad esempio, avere un'enumerazione di caratteri.CIOÈ:
enum MY_ENUM
{
CHAR_VALUE = 'c',
};
Vorrei assumere questo include __int64.Prova semplicemente
enum MY_ENUM
{
LARGE_VALUE = 0x1000000000000000,
};
Secondo il mio commentatore, sixlettervariables, in C il tipo base sarà sempre un int, mentre in C++ il tipo base è qualunque cosa sia abbastanza grande da adattarsi al valore incluso più grande.Quindi entrambe le enumerazioni sopra dovrebbero funzionare.
In MSVC++ puoi fare questo:
enum MYLONGLONGENUM:__int64 { BIG_KEY=0x3034303232303330, ...};