1

如果我有一个函数需要一个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());

我也无法改变

4

3 回答 3

5

是的你可以。

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());
}
于 2012-11-21T16:06:48.250 回答
3

我可能误解了这个问题,但你只需要:

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

如果您需要一个向后的迭代器,ipc 的答案会给您一个。

在实践中,vector你可能会侥幸逃脱while (begin != end--),但不要被诱惑。在迭代器位于向量开头的情况下(即当它等于 的结果时vector::begin())递减迭代器是未定义的行为。

此代码至少需要一个 BidirectionalIterator。幸运的是,vector有一个 RandomAccessIterator,它更好。

如果您真的只有一个 ForwardIterator,那么您必须遍历范围并将迭代器值存储在某处(如 a 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 一起工作)。

于 2012-11-21T16:07:29.623 回答
2

是的,您可以使用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;
}
于 2012-11-21T16:12:04.667 回答