Como converter int para enum em C ++?


222

Como converter um int para um enum em C ++?

Por exemplo:

enum Test
{
    A, B
};

int a = 1;

Como faço apara converter para o tipo Test::A?


1
link Observe que não importa se o int corresponde a uma das constantes do tipo enum; a conversão de tipo é sempre ilegal.
Iwaz 29/03

3
Acredito que se você deseja converter para Test :: A, o valor de int aterá que ser 0, porque Test :: A tem um valor implícito de 0 e Test :: B tem um valor implícito de 1. A menos que o fato de converter especificamente para Test :: a é além do ponto ...
JohnRDOrazio

Respostas:


243
int i = 1;
Test val = static_cast<Test>(i);

21
auto val = static_cast <Teste> (i); // C ++ 11
Mitch

3
@ Mitch, o que eu ganho por usar autoneste caso? Existe alguma melhoria de desempenho?
Frederico Pantuzza

2
Sem melhorias de desempenho. O compilador apenas deduz o tipo automaticamente se você especificar com "auto". Se você decidir alterar seu nome de enumeração no futuro, modificará menos seu código, pois o compilador deduzirá automaticamente o nome de tipo correto.
Aydin Özcan

74
Test e = static_cast<Test>(1);

10
MSDN: O operador static_cast pode converter explicitamente um valor integral em um tipo de enumeração. Se o valor do tipo integral não estiver dentro do intervalo de valores de enumeração, o valor de enumeração resultante será indefinido.
22412 Kirill Kobelev

1
@KirillKobelev se o valor integral puder ser representado pelo tipo subjacente da enumeração, a enumeração resultante deve ter esse valor. Caso contrário, o valor da enum produzido será o valor resultante da conversão da expressão no tipo subjacente da enum. Se o VC ++ faz algo diferente, acho que não é compatível.
bames53

2
o que um compilador conforme deve fazer, se enum tiver valores {1,3,5} e o código tentar fazer <static_cast> a partir do valor de 2. Como isso será diferente do C-cast?
Kirill Kobelev

6
@KirillKobelev Eu não estou usando um static_cast porque ele faz algo diferente de um estilo C, eu estou usando o static_cast porque os modelos C ++ são estilisticamente preferíveis aos modelos C.
bames53

4
@KirillKobelev " se enum tiver valores {1,3,5} " Não. O tipo de enumeração não pode ser limitado apenas a esses 3 valores possíveis: {1,3,5} são os enumeradores (nomeados valores de enumeração), não a enumeração em si . Se 1,3,5 são possíveis enumeração valores, então que assim é 2.
curiousguy

25

Seu código

enum Test
{
    A, B
}

int a = 1;

Solução

Test castEnum = static_cast<Test>(a);

45
É uma boa idéia usar o elenco mais restritivo que você puder e evitar completamente o estilo C, para dar ao compilador a melhor chance de detectar erros. static_castseria um elenco melhor aqui.
12118 Mike Seymour

4
@ Mike Seymour, o problema é que o elenco estático não tem diferença do elenco C neste caso. Como e que erro ele pode detectar ???
Kirill Kobelev

7
@KirillKobelev: O problema é que um elenco no estilo C não é explícito. Pode ser igual a static_cast, mas também pode ser uma const_castou até pior, uma reinterpret_castou mesmo uma combinação dessas. Mesmo se você souber agora o que irá degradar, suponha que você mude apara outro tipo mais tarde, pode muito bem ser o tipo de mudança de elenco sem que você receba um aviso, você não quer isso.
KillianDS

4
@KillianDS " suponha que você mude a para outro tipo mais tarde " qual tipo?
23412

2
Sim, aqueles ou um elenco implícito, se disponível. É muito mais claro qual é a intenção do elenco.
KillianDS

8

Girando fora a questão de encerramento, "como faço para converter um para digitar Test::A" ao invés de ser rígida sobre o requisito de ter um elenco de lá, e respondendo a vários anos de atraso apenas isso parece ser uma questão que ninguém popular, mais parece ter mencionado a alternativa , pelo padrão C ++ 11:

5.2.9 Molde estático

... uma expressão epode ser explicitamente convertida em um tipo T usando um static_castdo formulário static_cast<T>(e)se a declaração T t(e);estiver bem formada, para alguma variável temporária inventada t(8.5). O efeito de uma conversão explícita é o mesmo que executar a declaração e a inicialização e, em seguida, usar a variável temporária como resultado da conversão.

Portanto, o uso direto do formulário t(e)também funcionará, e você pode preferir o detalhe:

auto result = Test(a);

esta solução funcionou no caso de a opção do compilador ter bloqueado static_cast <> (verificação semântica). Não que isso faça sentido para mim, mas ainda limpo.
Buisson

1

Test castEnum = static_cast<Test>(a-1);converterá a em A. Se você não quiser o substrato 1, poderá redefinir enum:

enum Test
{
    A:1, B
};

Nesse caso, `Test castEnum = static_cast (a); ' pode ser usado para converter um para A.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.