С c ++ 11 существует альтернатива: писать простой шаблонный пользовательский итератор.
предположим, что ваше перечисление -
enum class foo {
one,
two,
three
};
. Этот общий код выполнит трюк, довольно эффективно - поместить в общий заголовок, он будет служить вам для любого перечисления, которое может понадобиться для повторения:
#include <type_traits>
template < typename C, C beginVal, C endVal>
class Iterator {
typedef typename std::underlying_type<C>::type val_t;
int val;
public:
Iterator(const C & f) : val(static_cast<val_t>(f)) {}
Iterator() : val(static_cast<val_t>(beginVal)) {}
Iterator operator++() {
++val;
return *this;
}
C operator*() { return static_cast<C>(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; }
};
Вам нужно будет выделить его
typedef Iterator<foo, foo::one, foo::three> fooIterator;
И затем вы можете выполнять итерацию с использованием range-for
for (foo i : fooIterator() ) { //notice the parenteses!
do_stuff(i);
}
. Предположение, что у вас нет пробелов в вашем перечислении, по-прежнему остается верным; нет предположения о количестве бит, фактически необходимых для хранения значения перечисления (благодаря std :: basic_type)