Обратная итерация по std :: vector с прямыми итераторами

Если у меня есть функция, которая принимает std::vector<T>::const_iterator называется начало и std::vector<T>::const_iterator называется конец, могу ли я перебрать его в обратном направлении?

ОБНОВИТЬ

Я не могу изменить сигнатуру функции, которая выглядит так:

void func(Foo::const_iterator begin, Foo::const_iterator end)
{
...
}

и позвонил с:

func(foo.begin(), foo.end());

который я тоже не могу изменить

0

Решение

Возможно, я неправильно понял вопрос, но вам просто нужно:

while (begin != end) {
--end;
// do something with *end
}

Если вам нужен итератор, работающий в обратном направлении, ответ от ipc даст вам один.

На практике с vector вы могли бы сойти с рук while (begin != end--)Но не поддавайтесь искушению. Неопределенное поведение — уменьшать итератор в случае, когда он находится в начале вектора (то есть, когда он равен результату vector::begin()).

Этот код требует по крайней мере двунаправленного Итератора. К счастью, vector есть RandomAccessIterator, который даже лучше.

Если у вас действительно был только ForwardIterator, то вам пришлось бы перебирать диапазон и сохранять значения итератора где-то (например, stack), а затем используйте их в обратном порядке:

std::stack<Foo::const_iterator> iterators;
while (begin != end) {
iterators.push(begin);
++begin;
}
while (!iterators.empty()) {
Foo::const_iterator i = iterators.top();
// do something with *i
iterators.pop();
}

Этот код требует как минимум ForwardIterator (он не будет работать с простым InputIterator).

3

Другие решения

Да, ты можешь.

template <typename Foo>
void test(typename Foo::const_iterator begin,
typename Foo::const_iterator end)
{
std::reverse_iterator<typename Foo::const_iterator>
rbegin(end),
rend(begin);
std::copy(rbegin, rend, std::ostream_iterator<typename std::iterator_traits<typename Foo::const_iterator>::value_type>(std::cout));
}

int main()
{
std::vector<int> v{3,1,4,1,5,9,2,6};
test<std::vector<int> >(v.begin(), v.end());
}
4

Да, вы можете использовать std::reverse_iterator, Это также хорошая идея, не
указать тип итератора явно. Используйте шаблон
аргумент вместо.

#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>

template <typename BidirectionalIterator>
void x(BidirectionalIterator b, BidirectionalIterator e) {
std::reverse_iterator<BidirectionalIterator> rb(e), re(b);
std::for_each(rb, re,
[](typename BidirectionalIterator::reference x)
{ std::cout << x << std::endl;});
}

int main()
{
std::vector<int> v{1,2,3,4};
x(begin(v), end(v));
return 0;
}
2
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector