Вы можете попытаться определить следующий макрос:
#define for_range(_type, _param, _A1, _B1) \
for (_type _param = _A1, _finish = _B1,\
_step = static_cast<_type>(2*(((int)_finish)>(int)_param)-1),\
_stop = static_cast<_type>(((int)_finish)+(int)_step); _param != _stop; \
_param = static_cast<_type>(((int)_param)+(int)_step))
Теперь вы можете использовать его:
for_range (unsigned, i, 10,0)
{
cout << "backwards i: " << i << endl;
}
Он может использоваться для итерации вперед и назад через целые числа без знака,enums и chars:
for_range (char, c, 'z','a')
{
cout << c << endl;
}
enum Count { zero, one, two, three };
for_range (Count, c, zero, three)
{
cout << "forward: " << c << endl;
}
Несмотря на неудобное определение, он очень хорошо оптимизирован.Я посмотрел на дизассемблер в VC ++.Код чрезвычайно эффективен.Не стоит откладывать, но три для операторов: компилятор будет производить только один цикл после оптимизации!Вы даже можете определить вложенные циклы:
unsigned p[4][5];
for_range (Count, i, zero,three)
for_range(unsigned int, j, 4, 0)
{
p[i][j] = static_cast<unsigned>(i)+j;
}
Очевидно, что вы не можете перебирать перечисляемые типы с пробелами.