Лучший / самый простой способ выполнить итерацию в обратном порядке - это (как уже было сказано) использовать обратные итераторы rbegin / rend.
Однако я хотел бы упомянуть, что обратные итераторы реализованы с сохранением «текущей» позиции итератора по одному (по крайней мере, в реализации стандартной библиотеки GNU).
Это сделано для упрощения реализации, чтобы обратный диапазон имел ту же семантику, что и диапазон вперед [начало, конец) и [rbegin, rend)
Это означает, что разыменование итератора включает создание нового временного объекта, а затем его уменьшение, каждый раз :
reference
operator*() const
{
_Iterator __tmp = current;
return *--__tmp;
}
Таким образом, разыменование обратного_тератора медленнее, чем обычный итератор.
Однако вместо этого вы можете использовать обычные двунаправленные итераторы, чтобы самим имитировать обратную итерацию, избегая таких издержек:
for ( iterator current = end() ; current != begin() ; /* Do nothing */ )
{
--current; // Unfortunately, you now need this here
/* Do work */
cout << *current << endl;
}
Тестирование показало, что это решение примерно в 5 раз быстрее для каждого разыменования , используемого в теле цикла.
Примечание: тестирование не было выполнено с кодом выше, так как этот std :: cout был бы узким местом.
Также обратите внимание: разница «время настенных часов» составляла ~ 5 секунд при размере std :: list в 10 миллионов элементов. Таким образом, на самом деле, если размер ваших данных не настолько велик, просто придерживайтесь rbegin () rend ()!