Итерация с size_t 0 в качестве граничного условия

Каков "правильный" способ записи уменьшающегося цикла с величиной size_t и граничным условием. Пример неправильной реализации:

for (size_t elemNum = listSize-1; elemNum >= 0; --elemNum) { /* ... */ }

Когда он достигнет нуля, он обернется к максимальному значению, а не будет действовать как граничное условие. Итерация петли в обратном случае необходима. Это похоже на проблему, которая будет иметь стандартное решение defacto, но я не могу найти, что это такое.

Ответы

Ответ 1

Самый сжатый подход - использовать пост-инкремент:

for (size_t i = listSize; i--;) ...

Ответ 2

elemNum = listsize;
while (elemNum--) {
    /* work with elemNum varying from `listsize - 1` down to `0` */
}

Ответ 3

Я не знаю стандартного способа, но это должно работать:

for (size_t elemNum = listSize-1; elemNum < listSize; --elemNum) { /* ... */ }

Ответ 4

Вместо этого вы можете использовать две переменные:

size_t count = 0;
for (size_t elemNum = listSize-1; count < listSize; ++count, --elemNum) { /* ... */ }

Ответ 5

for (size_t counter = listSize; counter > 0; --counter) { 
     size_t index = counter-1;

    /* ... use `index` as an index ... */ 
}

Ответ 6

size_t elemNum = listSize;
while (elemNum > 0) {
    --elemNum;
    // Do your work here.
}

Ответ 7

Вы можете использовать это как условие:

elemNum != (size_t)-1

Или вы можете подсчитать и выполнить некоторую математику (которая, вероятно, будет оптимизирована для компилятора) для вашего индекса:

for (size_t i = 1; i <= listSize; i++) {size_t elemNum = listSize-i; /* */}

Ответ 8

Если вы можете гарантировать, что начальное значение не слишком велико, простой ответ: вместо этого используйте подписанный тип.

Ответ 9

Стандартный способ С++ - использовать std::reverse_iterator.

Как-то в цикле вы получаете доступ к элементу elemNum списка, скажем, через list[elemNum], где list моделирует концепцию RandomAccessIterator. Предположим, что list_iterator_type является идентификатором list. Ваша петля с использованием обратных итераторов становится:

std::reverse_iterator<list_iterator_type> it, end = std::reverse_iterator<list_iterator_type>(list);
for (it = std::reverse_iterator<list_iterator_type>(list + listSize); it != end; ++it) {
    // `*it` is `list[elemNum]`
}