此类迭代器可以使得算法能够以逆向(reverse mode)模式,安插模式(insert mode)进行工作,也可以流(streams)的模式搭配工作
reverse迭代器是一种适配器,重新定义递增运算和递减运算,使其行为正好倒置,所有标准容器都允许使用reverse迭代器来遍历元素,例子
#include <iostream>
#include <list>
#include <iterator>
#include <algorithm>
#include <vector>
using namespace std;
void print(int elem)
{
cout << elem << ' ';
}
int main(void)
{
list<int> col;
for (int i=1; i<=9; ++i)
col.push_back(i);
for_each(col.begin(),col.end(),print);
cout << endl;
for_each(col.rbegin(),col.rend(),print);
cout << endl;
return 0;
}
而for_each()代码如下
namespace std
{
template <typename Iterator, class Operation>
Operation for_each (Iterator act, Iterator end, Operation op)
{
while (act != end)
op(*act);
++act;
}
return op;
}
容器的成员函数rbegin()和rend()各自返回一个逆向迭代器。也就是说rbegin()返回容器的尾部,而rend()返回容器的头部的前一个,因此就能解释为什么会出现逆向行为了。
通过如下代码更能清楚解释
rbegin() = container::reverse_iterator(end());
rend() = container::reverse_iterator(begin());
而逆向迭代器的++操作是会向反方向进行的
可以将一般迭代器转化为一个reverse迭代器,当然原来的迭代器必须具有双向移动能力,注意转换前后迭代器的逻辑位置发生了变化
先看一例子
#include <iostream>
#include <list>
#include <iterator>
#include <algorithm>
#include <vector>
using namespace std;
void print(int elem)
{
cout << elem << ' ';
}
int main(void)
{
vector<int> col;
for (int i=1; i<=9; ++i)
col.push_back(i);
vector<int>::iterator pos;
pos = find(col.begin(),col.end(),5);
cout << "pos=" << *pos << endl;
vector<int>::reverse_iterator rpos(pos);
cout << "rpos=" << *rpos << endl;
return 0;
}
/* 程序输出 pos=5 rpos=4 */
为什么会这样?迭代器转换为逆向迭代器的时候发生了什么?
答:当迭代器转换为逆向迭代器的时候,它们指向同一个实际地点,但它们所代表的意义却不同了。
注意这是特性,主要由半开原则造成的,具体解释见下图即可
如果你有个区间,由两个迭代器定义出来,那么操作就会很简单,所有元素任然有效,你就会看出STL这样设计的优点。见下例子1
#include <iostream>
#include <deque>
#include <iterator>
#include <algorithm>
using namespace std;
int main(void)
{
deque<int> col;
for (int i=1; i<=9; ++i)
col.push_back(i);
deque<int>::iterator pos1,pos2;
pos1 = find(col.begin(),col.end(),2);
pos2 = find(col.begin(),col.end(),7);
copy(pos1,pos2,ostream_iterator<int>(cout," ")); // 2 3 4 5 6
cout << endl;
deque<int>::reverse_iterator rpos1(pos1);
deque<int>::reverse_iterator rpos2(pos2);
//copy(rpos1,rpos2,ostream_iterator<int>(cout," ")); //没打印,为什么
copy(rpos2,rpos1,ostream_iterator<int>(cout," ")); // 6 5 4 3 2
cout << endl;
return 0;
}
见下例子2
#include <iostream>
#include <deque>
#include <iterator>
#include <algorithm>
using namespace std;
void print(int elem)
{
cout << elem << ' ';
}
int main(void)
{
deque<int> col;
for (int i=1; i<=9; ++i)
col.push_back(i);
deque<int>::iterator pos1,pos2;
pos1 = find(col.begin(),col.end(),2);
pos2 = find(col.begin(),col.end(),7);
for_each(pos1,pos2,print); // 2 3 4 5 6
cout << endl;
deque<int>::reverse_iterator rpos1(pos1);
deque<int>::reverse_iterator rpos2(pos2);
// for_each(rpos1,rpos2,print); //错误
for_each(rpos2,rpos1,print); // 6 5 4 3 2
cout << endl;
return 0;
}
/* 刚开始写错了: 其实看看for_each()的源代码(源代码见上)就可以知道原因了: rpos2在rpos1,因此会产生上面的错误 */
base()是reverse_iterator型别的一个成员函数,
见下面例子
#include <iostream>
#include <deque>
#include <iterator>
#include <algorithm>
using namespace std;
int main(void)
{
deque<int> col;
for (int i=1; i<=9; ++i)
col.push_back(i);
deque<int>::iterator pos;
pos = find(col.begin(),col.end(),3);
cout << "*pos = " << *pos << endl; // 3
deque<int>::reverse_iterator rpos(pos);
cout << "*rpos = " << *rpos << endl; // 2
//deque<int>::reverse_iterator rpos(pos);这样写错误
deque<int>::iterator rrpos;
rrpos = rpos.base();
cout << "*rrpos = " << *rrpos << endl; // 3
return 0;
}
逆向迭代器的相关声明继使用方法如下
container::iterator pos;
...
container::reverse_iterator rpos(pos);
...
pos = rpos.base();
注意使用STL算法时,若区间由逆向迭代器组成,一定多注意区间的有效性