Pergunta

Existe uma maneira de ter um enum de 64 bits em C++?Ao refatorar algum código, me deparei com um monte de #defines que seriam melhores como uma enumeração, mas ser maior que 32 bits causa erro no compilador.

Por alguma razão, pensei que o seguinte poderia funcionar:

enum MY_ENUM : unsigned __int64  
{  
    LARGE_VALUE = 0x1000000000000000,  
};
Foi útil?

Solução

Não acho que isso seja possível com C++ 98.A representação subjacente de enums depende do compilador.Nesse caso, é melhor usar:

const __int64 LARGE_VALUE = 0x1000000000000000L;

A partir do C++ 11, é possível usar classes enum para especificar o tipo base do enum:

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

Além disso, as classes enum introduzem um novo escopo de nome.Então, em vez de se referir a LARGE_VALUE, você faria referência MY_ENUM::LARGE_VALUE.

Outras dicas

C++ 11 suporta isso, usando esta sintaxe:

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

O actual projecto do chamado C++0x, isso é n3092 diz em 7.2 Declarações de enumeração, parágrafo 6:

É definido por implementação qual tipo integral é usado como tipo subjacente, exceto que o tipo subjacente não deve ser maior que o INT, a menos que o valor de um enumerador não possa se encaixar em um int ou não assinado int.

O mesmo parágrafo também diz:

Se nenhum tipo integral puder representar todos os valores do enumerador, a enumeração será mal formada.

Minha interpretação da parte a menos que o valor de um enumerador não caiba em um int ou unsigned int é que é perfeitamente válido e seguro inicializar o enumerador com valor inteiro de 64 bits, desde que haja um tipo inteiro de 64 bits fornecido em uma implementação específica de C++.

Por exemplo:

enum MyEnum
{
    Undefined = 0xffffffffffffffffULL
};

As respostas referentes __int64 perca o problema.A enumeração é válido em todos os compiladores C++ que possuem um tipo integral verdadeiro de 64 bits, ou seja,qualquer compilador C++ 11 ou compiladores C++ 03 com extensões apropriadas.Extensões para C++ 03 como __int64 funcionam de maneira diferente entre compiladores, incluindo sua adequação como tipo base para enums.

Se o compilador não suportar enums de 64 bits por sinalizadores de compilação ou qualquer outro meio, acho que não há solução para este.

Você poderia criar algo como em sua amostra algo como:

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

e usá-lo como um enum usando

MyNamespace::LARGE_VALUE 

ou

using MyNamespace;
....
val = LARGE_VALUE;

Como você está trabalhando em C++, outra alternativa pode ser

const __int64 LARVE_VALUE = ...

Isso pode ser especificado em um arquivo H.

seu trecho de código não é o padrão c++:

enum MEU_ENUM:não assinado __int64

não faz sentido.

use const __int64 em vez disso, como sugere Torlack

O tipo de enum normalmente é determinado pelo tipo de dados do primeiro inicializador de enum.Se o valor exceder o intervalo para esse tipo de dados integral, o compilador c ++ garantirá que ele se encaixe usando um tipo de dados integral maior. Se o compilador descobrir que não pertence a nenhum tipo de dados integral, o compilador gerará um erro.Referência: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf
Editar:No entanto, isso depende puramente da arquitetura da máquina

Um enum em C++ pode ser de qualquer tipo integral.Você pode, por exemplo, ter uma enumeração de caracteres.Ou seja:

enum MY_ENUM
{
   CHAR_VALUE = 'c',
};

Eu poderia presumir isso inclui __int64.Tente apenas

enum MY_ENUM
{
   LARGE_VALUE = 0x1000000000000000,
};

De acordo com meu comentarista, variáveis ​​​​de seis letras, em C o tipo base será sempre um int, enquanto em C++ o tipo base é o que for grande o suficiente para caber no maior valor incluído.Portanto, ambas as enumerações acima devem funcionar.

No MSVC++ você pode fazer isso:

enum MYLONGLONGENUM:__int64 { BIG_KEY=0x3034303232303330, ...};

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top