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,  
};
È stato utile?

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, ...};

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top