Если у меня есть функция, которая принимает 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());
который я тоже не могу изменить
Возможно, я неправильно понял вопрос, но вам просто нужно:
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).
Да, ты можешь.
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());
}
Да, вы можете использовать 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;
}