use*_*ser 78 c++ iterator vector
是否可以迭代从结尾到开头的向量?
for (vector<my_class>::iterator i = my_vector.end();
i != my_vector.begin(); /* ?! */ ) {
}
Run Code Online (Sandbox Code Playgroud)
或者只有这样的东西才有可能:
for (int i = my_vector.size() - 1; i >= 0; --i) {
}
Run Code Online (Sandbox Code Playgroud)
Jam*_*ran 130
那么,最好的方法是:
for (vector<my_class>::reverse_iterator i = my_vector.rbegin();
i != my_vector.rend(); ++i ) {
}
Run Code Online (Sandbox Code Playgroud)
rbegin()/ rend()特别为此目的而设计.(是的,递增reverse_interator会向后移动)
现在,从理论上讲,你的方法(使用begin/end&rbegin())可以工作,vector的迭代器是双向的,但是请记住,end()不是最后一个元素 - 它是超出最后一个元素的一个,所以你必须减少首先,当你到达begin()时就完成了 - 但是你仍然需要进行处理.
vector<my_class>::iterator i = my_vector.end();
while (i != my_vector.begin())
{
--i;
/*do stuff */
}
Run Code Online (Sandbox Code Playgroud)
更新:我显然过于积极地将for()循环重写为while循环.(重要的部分是rend()开头的.)
Aka*_*all 43
如果有auto,你可以利用auto.
for (auto it = my_vector.rbegin(); it != my_vector.rend(); ++it)
{
}
Run Code Online (Sandbox Code Playgroud)
flo*_*tan 27
从 c++20 开始,您可以使用 astd::ranges::reverse_view和基于范围的 for 循环:
#include<ranges>
#include<vector>
#include<iostream>
using namespace std::ranges;
std::vector<int> const vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for(auto& i : views::reverse(vec)) {
std::cout << i << ",";
}
Run Code Online (Sandbox Code Playgroud)
甚至
for(auto& i : vec | views::reverse)
Run Code Online (Sandbox Code Playgroud)
不幸的是,在撰写本文时(2020 年 1 月),还没有主要编译器实现Ranges库,但您可以求助于Eric Niebler 的 Ranges-v3:
#include <iostream>
#include <vector>
#include "range/v3/all.hpp"
int main() {
using namespace ranges;
std::vector<int> const vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for(auto& i : views::reverse(vec)) {
std::cout << i << ",";
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
AnT*_*AnT 24
通过闭合开放范围反向迭代的完善的"模式"如下所示
// Iterate over [begin, end) range in reverse
for (iterator = end; iterator-- != begin; ) {
// Process `*iterator`
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您愿意,
// Iterate over [begin, end) range in reverse
for (iterator = end; iterator != begin; ) {
--iterator;
// Process `*iterator`
}
Run Code Online (Sandbox Code Playgroud)
例如,该模式可用于使用无符号索引对数组进行反向索引
int array[N];
...
// Iterate over [0, N) range in reverse
for (unsigned i = N; i-- != 0; ) {
array[i]; // <- process it
}
Run Code Online (Sandbox Code Playgroud)
(不熟悉此模式的人经常坚持使用有符号整数类型进行数组索引,因为他们错误地认为无符号类型会阻止反向索引)
它可以用于使用"滑动指针"技术迭代数组
// Iterate over [array, array + N) range in reverse
for (int *p = array + N; p-- != array; ) {
*p; // <- process it
}
Run Code Online (Sandbox Code Playgroud)
或者它可以用于使用普通(非反向)迭代器对向量进行反向迭代
for (vector<my_class>::iterator i = my_vector.end(); i-- != my_vector.begin(); ) {
*i; // <- process it
}
Run Code Online (Sandbox Code Playgroud)
用户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));
}
Run Code Online (Sandbox Code Playgroud)
然后:
for( auto rit = reversed(data.end()); rit != reversed(data.begin()); ++rit ) {
std::cout << *rit;
Run Code Online (Sandbox Code Playgroud)
或者在C++ 14中只做:
for( auto rit = std::rbegin(data); rit != std::rend(data); ++rit ) {
std::cout << *rit;
Run Code Online (Sandbox Code Playgroud)
在C++ 03/11中,大多数标准容器都有一个.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) ) };
}
Run Code Online (Sandbox Code Playgroud)
现在你可以这样做:
for (auto&& x : backwards(ctnr))
std::cout << x;
Run Code Online (Sandbox Code Playgroud)
我认为这很漂亮.