从头到尾,迭代C ++向量
是否有可能从头到尾迭代一个向量?
for (vector<my_class>::iterator i = my_vector.end(); i != my_vector.begin(); /* ?! */ ) { }
或者只有这样的可能性:
for (int i = my_vector.size() - 1; i >= 0; --i) { }
那么最好的方法是:
for (vector<my_class>::reverse_iterator i = my_vector.rbegin(); i != my_vector.rend(); ++i ) { }
rbegin()/ rend()专门为此devise的。 (是的,增加一个reverse_interator向后移动它)
现在,在理论上,你的方法(使用begin / end&– --i
)会起作用,vector的迭代器是双向的,但记住,end()不是最后一个元素 – 它是最后一个元素之外的元素,必须首先减less,到达begin()时完成 – 但仍然需要处理。
vector<my_class>::iterator i = my_vector.end(); while (i != my_vector.begin()) { --i; /*do stuff */ ) }
更新:我显然过于积极重新写for()循环到一个while循环。 (重要的部分是 – --i
是在开始。)
如果你有C++11
,你可以使用auto
。
for (auto it = my_vector.rbegin(); it != my_vector.rend(); ++it) { }
反向迭代通过闭合开放范围的完善“模式”如下所示
// Iterate over [begin, end) range in reverse for (iterator = end; iterator-- != begin; ) { // Process `*iterator` }
或者,如果你愿意,
// Iterate over [begin, end) range in reverse for (iterator = end; iterator != begin; ) { --iterator; // Process `*iterator` }
例如,此模式可用于使用无符号索引对数组进行反向索引
int array[N]; ... // Iterate over [0, N) range in reverse for (unsigned i = N; i-- != 0; ) { array[i]; // <- process it }
(不熟悉这种模式的人经常坚持使用带符号整数types来进行数组索引,因为他们错误地认为无符号types会阻止反向索引)
它可以用于使用“滑动指针”技术迭代数组
// Iterate over [array, array + N) range in reverse for (int *p = array + N; p-- != array; ) { *p; // <- process it }
或者它可以用于使用普通(而不是反向)迭代器对向量进行反向迭代
for (vector<my_class>::iterator i = my_vector.end(); i-- != my_vector.begin(); ) { *i; // <- process it }
用户rend() / rbegin()
迭代器:
for (vector<myclass>::reverse_iterator it = myvector.rbegin(); it != myvector.rend(); it++)
template<class It> std::reverse_iterator<It> reversed( It it ) { return std::reverse_iterator<It>(std::forward<It>(it)); }
然后:
for( auto rit = reversed(data.end()); rit != reversed(data.begin()); ++rit ) { std::cout << *rit;
或者在C ++ 14中做:
for( auto rit = std::rbegin(data); rit != std::rend(data); ++rit ) { std::cout << *rit;
在C ++ .rbegin()
大多数标准容器都有一个.rbegin()
和.rend()
方法。
最后,您可以backwards
写入范围适配器,如下所示:
namespace adl_aux { using std::begin; using std::end; template<class C> decltype( begin( std::declval<C>() ) ) adl_begin( C&& c ) { return begin(std::forward<C>(c)); } template<class C> decltype( end( std::declval<C>() ) ) adl_end( C&& c ) { return end(std::forward<C>(c)); } } template<class It> struct simple_range { It b_, e_; simple_range():b_(),e_(){} It begin() const { return b_; } It end() const { return e_; } simple_range( It b, It e ):b_(b), e_(e) {} template<class OtherRange> simple_range( OtherRange&& o ): simple_range(adl_aux::adl_begin(o), adl_aux::adl_end(o)) {} // explicit defaults: simple_range( simple_range const& o ) = default; simple_range( simple_range && o ) = default; simple_range& operator=( simple_range const& o ) = default; simple_range& operator=( simple_range && o ) = default; }; template<class C> simple_range< decltype( reversed( adl_aux::adl_begin( std::declval<C&>() ) ) ) > backwards( C&& c ) { return { reversed( adl_aux::adl_end(c) ), reversed( adl_aux::adl_begin(c) ) }; }
现在你可以做到这一点:
for (auto&& x : backwards(ctnr)) std::cout << x;
我觉得这很漂亮。
使用反向迭代器并从rbegin()
循环到rend()
使用这个代码
//print the vector element in reverse order by normal iterator. cout <<"print the vector element in reverse order by normal iterator." <<endl; vector<string>::iterator iter=vec.end(); --iter; while (iter != vec.begin()) { cout << *iter << " "; --iter; }