Есть четвертый вариант (не обязательно хороший вариант, но он существует). Вы можете использовать итераторы двунаправленного / произвольного доступа таким образом, чтобы имитировать, как реализованы обратные итераторы, чтобы избежать проблемы с myvec.end()-1
на пустом итераторе:
for (vector<int>::iterator it = myvec.end(); it != myvec.begin(); --it)
{
// convert the loop controlling iterator to something that points
// to the item we're really referring to
vector<int>::iterator true_it = it;
--true_it;
// do stuff here
// but always dereference `true_it` instead of `it`
// this is essentially similar to the way a reverse_iterator
// generally works
int& x = *true_it;
}
или даже:
for (vector<int>::iterator it = myvec.end(); it != myvec.begin();)
{
// decrement `it` before the loop executes rather than after
// it's a bit non-idiomatic, but works
--it;
int& x = *it;
// do stuff...
}
Как я уже сказал, это не обязательно хороший вариант (я думаю ответ Джерри Коффина - это подход, на который вы должны обратить внимание в первую очередь), но я думаю, что он представляет интерес, поскольку показывает, как работают обратные итераторы сцены - и это избавляет от необходимости конвертировать reverse_iterator в итератор для тех случаев, когда вы можете использовать итератор с чем-то, что не принимает reverse_iterator
(преобразование reverse_iterator
s в iterator
s всегда кажется у меня болит голова, поэтому я часто избегаю reverse_iterators
, чтобы избежать головной боли). Например, если вы хотите вызвать insert () для местоположения, обратный итератор ссылается на:
// if `it` is a reverse iterator, a call to insert might have to look something like:
myvec.insert( --(it.base()), 42 ); // assume that you know the current vector capacity
// will avoid a reallocation, so the loop's
// iterators won't be invalidated
// if `it` is a normal iterator...
myvec.insert( it, 42 );