Recuerda que en las ciencias un error suele tener varias resoluciones, por lo tanto nosotros compartimos lo más óptimo y mejor.
Solución:
La forma típica es la siguiente:
enum Foo
One,
Two,
Three,
Last
;
for ( int fooInt = One; fooInt != Last; fooInt++ )
Foo foo = static_cast(fooInt);
// ...
Tenga en cuenta que la enumeración Last
está destinado a ser omitido por la iteración. Utilizando este “falso” Last
enumeración, no tiene que actualizar su condición de terminación en el bucle for a la última enumeración “real” cada vez que desee agregar una nueva enumeración. Si desea agregar más enumeraciones más tarde, simplemente agréguelas antes de Último. El bucle de este ejemplo seguirá funcionando.
Por supuesto, esto se descompone si se especifican los valores de enumeración:
enum Foo
One = 1,
Two = 9,
Three = 4,
Last
;
Esto ilustra que una enumeración no está realmente destinada a iterar. La forma típica de lidiar con una enumeración es usarla en una declaración de cambio.
switch ( foo )
case One:
// ..
break;
case Two: // intentional fall-through
case Three:
// ..
break;
case Four:
// ..
break;
default:
assert( ! "Invalid Foo enum value" );
break;
Si realmente desea enumerar, rellene los valores de enumeración en un vector e itere sobre eso. Esto también se ocupará correctamente de los valores de enumeración especificados.
#include
#include
namespace MyEnum
enum Type
a = 100,
b = 220,
c = -1
;
static const Type All[] = a, b, c ;
void fun( const MyEnum::Type e )
std::cout << e << std::endl;
int main()
// all
for ( const auto e : MyEnum::All )
fun( e );
// some
for ( const auto e : MyEnum::a, MyEnum::b )
fun( e );
// all
std::for_each( std::begin( MyEnum::All ), std::end( MyEnum::All ), fun );
return 0;
Con c ++ 11, en realidad hay una alternativa: escribir un iterador personalizado simple con plantilla.
supongamos que su enumeración es
enum class foo
one,
two,
three
;
Este código genérico hará el truco, de manera bastante eficiente: colóquelo en un encabezado genérico, le servirá para cualquier enumeración que necesite iterar:
#include
template < typename C, C beginVal, C endVal>
class Iterator
typedef typename std::underlying_type::type val_t;
int val;
public:
Iterator(const C & f) : val(static_cast(f))
Iterator() : val(static_cast(beginVal))
Iterator operator++()
++val;
return *this;
C operator*() return static_cast(val);
Iterator begin() return *this; //default ctor is good
Iterator end()
static const Iterator endIter=++Iterator(endVal); // cache it
return endIter;
bool operator!=(const Iterator& i) return val != i.val;
;
Tendrás que especializarlo
typedef Iterator fooIterator;
Y luego puedes iterar usando range-for
for (foo i : fooIterator() ) //notice the parentheses!
do_stuff(i);
La suposición de que no tiene lagunas en su enumeración sigue siendo true; no hay ninguna suposición sobre la cantidad de bits que realmente se necesitan para almacenar el valor de enumeración (gracias a std::underlying_type)
Más adelante puedes encontrar las anotaciones de otros administradores, tú aún puedes mostrar el tuyo si lo crees conveniente.