Come lanciare int per enumare in C ++?


222

Come faccio a lanciare un int in un enum in C ++?

Per esempio:

enum Test
{
    A, B
};

int a = 1;

Come faccio a convertire ain tipo Test::A?


1
link Nota che non importa se int corrisponde a una delle costanti del tipo enum; la conversione del tipo è sempre illegale.
Iwaz,

3
Credo che se si desidera eseguire il cast su Test :: A il valore di int adovrà essere 0, perché Test :: A ha un valore implicito di 0 e Test :: B ha un valore implicito di 1. A meno che il fatto del cast in particolare per Test :: A è oltre il punto ...
JohnRDOrazio

Risposte:


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

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

3
@Mitch cosa ottengo per l'utilizzo autoin questo caso? Ci sono miglioramenti delle prestazioni?
Frederico Pantuzza,

2
Nessun miglioramento delle prestazioni. Il compilatore deduce solo automaticamente il tipo se si specifica con "auto". Se deciderai di cambiare il tuo nome enum in futuro, modificherai il codice meno poiché il compilatore dedurrà automaticamente il nome corretto del tipo.
Aydin Özcan,

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

10
MSDN: l'operatore static_cast può convertire esplicitamente un valore integrale in un tipo di enumerazione. Se il valore del tipo integrale non rientra nell'intervallo dei valori di enumerazione, il valore di enumerazione risultante non è definito.
Kirill Kobelev,

1
@KirillKobelev se il valore integrale può essere rappresentato dal tipo sottostante dell'enum, allora l'enum risultante deve avere quel valore. Altrimenti il ​​valore enum prodotto sarà qualunque valore derivi dalla conversione dell'espressione nel tipo sottostante dell'enum. Se VC ++ fa qualcosa di diverso, penso che non sia conforme.
bames53,

2
cosa dovrebbe fare un compilatore conforme, se enum ha valori {1,3,5} e il codice tenta di fare <static_cast> dal valore di 2. In che modo differirà dal C-cast?
Kirill Kobelev,

6
@KirillKobelev Non sto usando un static_cast perché fa qualcosa di diverso da un cast in stile C, sto usando static_cast perché i cast C ++ sono stilisticamente preferibili ai cast C.
bames53,

4
@KirillKobelev " se enum ha valori {1,3,5} " No. Il tipo di enumerazione non può essere limitato solo a questi 3 valori possibili: {1,3,5} sono gli enumeratori (denominati valori di enumerazione), non l'enumerazione stessa . Se 1,3,5 sono possibili valori di enumerazione , allora lo è anche 2.
curiousguy,

25

Il tuo codice

enum Test
{
    A, B
}

int a = 1;

Soluzione

Test castEnum = static_cast<Test>(a);

45
È una buona idea usare il cast più restrittivo possibile ed evitare del tutto i cast in stile C, per dare al compilatore le migliori possibilità di rilevare errori. static_castsarebbe un cast migliore qui.
Mike Seymour,

4
@ Mike Seymour, il problema è che in questo caso il cast statico non ha alcuna differenza rispetto al C-cast. Come e quale errore può rilevare ???
Kirill Kobelev,

7
@KirillKobelev: il problema è che un cast in stile C non è esplicito. Può essere uguale a a static_cast, ma potrebbe anche essere una const_casto anche peggio, una reinterpret_casto anche una combinazione di quelli. Anche se ora sai in cosa si degraderà, supponi di passare aa un altro tipo in seguito, potrebbe benissimo essere il tipo di modifiche al cast senza che tu abbia mai ricevuto un avviso, non lo vuoi.
KillianDS,

4
@KillianDS " supponi di cambiare in un altro tipo in seguito " quale tipo?
curiousguy,

2
Sì, quelli o un cast implicito, se disponibile. È molto più chiaro quale sia l'intento del cast.
KillianDS,

8

Rifiutando la domanda di chiusura, "come faccio a convertire un tipo Test::A" piuttosto che essere rigido riguardo al requisito di avere un cast lì dentro, e rispondere con diversi anni di ritardo proprio questa sembra essere una domanda popolare che nessun altro sembra aver menzionato l'alternativa , secondo lo standard C ++ 11:

5.2.9 Cast statico

... un'espressione epuò essere esplicitamente convertita in un tipo T usando a static_castdel modulo static_cast<T>(e)se la dichiarazione T t(e);è ben formata, per alcune variabili temporanee inventate t(8.5). L'effetto di una tale conversione esplicita è lo stesso dell'esecuzione della dichiarazione e dell'inizializzazione e quindi dell'uso della variabile temporanea come risultato della conversione.

Pertanto, anche l'utilizzo diretto del modulo t(e)funzionerà e potresti preferirlo per la pulizia:

auto result = Test(a);

questa soluzione ha funzionato nel caso l'opzione del compilatore fosse bloccata static_cast <> (controllo semantico). Non che abbia senso per me, ma comunque pulito.
Mr Buisson,

1

Test castEnum = static_cast<Test>(a-1);lancerà a su A. Se non si desidera il substrato 1, è possibile ridefinire enum:

enum Test
{
    A:1, B
};

In questo caso `Test castEnum = static_cast (a); ' potrebbe essere usato per lanciare a su A.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.