2013-07-22 12 views
5

Ci sono molti modi per scorrere enumerazioni consecutivi comeiterate attraverso elementi enum non consecutivi in ​​C++

enum Animal {Cat, Dog, Dolphin} 

ma c'è un modo conveniente e facile da scorrere elementi enum non consecutivi come

enum Animal {Cat = 0, Dog = 5, Dolphin = 8} 
+0

Non sul 'enum' direttamente. Comunque puoi mettere manualmente tutti gli elementi di 'enum' in un contenitore (' vector', 'set',' unordered_set', qualunque cosa ...) e poi scorrere su quel contenitore. – syam

+0

Vuoi dire qualcosa come 'per (Animale a = Gatto; a! = Dolphin; a ++)'? Mentre questo funziona per la prima enumerazione, non è qualcosa che raccomanderò personalmente, in quanto potrebbe essere difficile da leggere e capire. –

+2

È possibile trovare la risposta in questo thread http: // StackOverflow.it/questions/261963/how-can-i-iterate-over-an-enum. – blitz

risposta

2

La risposta breve a questo è "no".

È possibile creare una tabella animals e quindi utilizzare un ciclo di intervallo su animals.

Ecco un "demo" completo:

#include <iostream> 

using namespace std; 

enum Animal {Cat = 0, Dog = 5, Dolphin = 8}; 

int main() 
{ 
    Animal animals[] = { Cat, Dog, Dolphin }; 

    for(Animal a : animals) cout << a << endl; 
} 

L'output sarà:

0 
5 
8 
0

Non sono sicuro che la questione rende ancora senso. È a qualsiasi tariffa fondamentalmente impossibile. Considerate:

enum Animal 
{ 
    cat = 0, 
    dog = 5, 
    dolphin = 8, 
    canine = 5, 
    bear = 20 
}; 

Quando il valore di fondo è 5, non si ha modo di determinare se sia stata impostata dog o canine, e quindi non c'è modo di sapere se il valore successivo dovrebbe essere dolphin o bear. È possibile inserire i valori in un array e scorrere su di esso, ma Non vedo altre soluzioni.

In generale, naturalmente, la maggior parte del tempo si sta esplicitamente valori che interessano come questo questo, si sta definendo una maschera di bit (ad esempio come std::ios_base::fmtflags), e in tal caso, non ha senso per iterare . Altri casi d'uso mi viene in mente sarebbe valori speciali Sentinal (ad esempio, qualcosa come unset), che si sarebbe probabilmente desidera saltare quando l'iterazione, o sinonimi (come il mio dog/canine esempio di cui sopra), nel qual caso, è' d probabilmente vogliono solo visitare uno dei sinonimi, e realisticamente, ci si scrivere qualcosa di simile:

enum Animal 
{ 
    cat, 
    dog, 
    canine = dog, 
    dolphin, 
    bear 
}; 

, ed i soliti trucchi di iterazione si tradurrebbe in esattamente quello che vuoi .

1

Si potrebbe anche fornire all'operatore necessario (s) per l'enumerazione:

enum Animal 
{ 
    Cat = 0 
    , Dog = 5 
    , Dolphin = 8 
}; 

inline Animal& operator++ (Animal &x) 
{ 
    switch (x) { 
    case Cat: 
     x = Dog; 
     break; 
    case Dog: 
     x = Dolphin; 
     break; 
    case Dolphin: 
    default: 
     x = static_cast<Animal>(static_cast<int>(x) + 1); 
     break; 
    } 
    return x; 
} 

DTTO per postfix ++, < e qualsiasi altra cosa si ha bisogno. Certo, devi tenerli sincronizzati con la definizione dell'enumerazione. Non proprio semplice, ma è un'opzione.

Problemi correlati