迭代器和反向迭代器,常量迭代器和非常量迭代器

 迭代器的类型共有4种:<T>::Iiterator,<T>::const_iterator,<T>::reverse_iterator,<T>::const_reverse_iterator

#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
string line = "you,are,robert";
//返回结果是常量反向迭代器,所以这里必须定义一个常量反向迭代器
string::const_reverse_iterator it = find(line.crbegin(),line.crend(),',');
cout << *it << endl;
//line.crbegin()必须在it的前面,这两个迭代器必须保持字面的先后顺序
//(rbegin就在最前面,rend最后)
string  word(line.crbegin(),it);
//string new_word(word.rbegin(),word.rend());
//sort(word.begin(),word.end());
//sort(word.rbegin(),word.rend());
cout << "cout the word:" << endl;
cout << word << endl;
for(auto i = word.rbegin();i != word.rend();++i)
	cout  << *i;

return 0;
}
#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
string line = "you,are,robert";
//返回的是常量的反向迭代器,这里也必须定义相同的类型
string::const_reverse_iterator it = find(line.crbegin(),line.crend(),',');
cout << *it << endl;
//下面的两个迭代器必须类型完全一致(常量特性,是否反向迭代器,crbegin()必须在最前面)
string  word(line.crbegin(),it);
//这里it.base()已经是一个普通的常量迭代器,注意it.base()得到的和it的常量特性是相同的
//所以line.cend()也是一个常量迭代器
string  new_word(it.base(),line.cend());
cout << new_word << endl;
  return 0;
}

注意:自己总结出如下规则(不足之处批评指正)

(1)reverse_iterator有base()成员函数,可以返回它的普通迭代器.

(2)反向迭代器转换为普通迭代器时候,不改变const特性,例如:string::const_reverse_iterator it      it.base()也是一个常量迭代器,因为转换不改变常量特性

(3)在初始化其余容器类型时候,begin()必须在end()之前(如果有中间元素迭代器也一样),rbegin()必须在rend()之前(如果有中间元素的迭代器也一样)。即迭代器或者反向迭代器必须遵循理论上字面顺序。

(4)用一对迭代器初始化别的容器类型对象的时候,常量特性必须保持一致,是否是反向迭代器也必须一致(尽管通常不用反向迭代器初始化一个string对象,因为会把每个字母倒过来解读)。

例如 vector<int>  elem(it1,it2);it1和it2如果一个是常量迭代器,另一个也必须是(或者都不是常量迭代器)。

而且it1和it2要么都是反向迭代器,要么都不是反向迭代器。

(5)如果是两个迭代器比较的时候,只要只想同一个元素,如果仅仅只有const的差别,那么结果是相等的。

(6)反向迭代器和普通迭代器调用算法的时候:

把普通迭代器初始化反向迭代器,最后得到一组反向迭代器范围,那么处理的范围是一样的,例如:


#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <forward_list>
#include <stack>
#include <vector>
#include <forward_list>
#include <deque>
#include <array>
#include <list>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
//这里假设要反向打印vector中第二个到第七个元素:
	
vector<int> vint{1,2,3,4,5,6,7,8,9,0};

ostream_iterator<int> out_iter(cout);

//那么根据迭代器的左闭右开准则,给的范围是3-8个,
//接下来把迭代器的3-8个元素转变为反向迭代器it3和it4,
//(it4,it3)这个处理范围对应3-8个范围
//一句话:把一对普通迭代器转换成反向迭代器,处理的范围和原来迭代器范围一样
//运行结果是:76543
vector<int>::reverse_iterator it3(vint.begin() + 2),it4(vint.begin() + 7);
copy(it4,it3,out_iter);

//反过来,把一对反向迭代器转化成普通迭代器后,处理范围会改变吗?
vector<int>::iterator i1 = it3.base(),i2 = it4.base();
copy(i1,i2,out_iter);
//运行结果是 34567



return 0;
}

(7)c++ primer(5th)365页上说,从普通迭代器给反向迭代器赋值或者初始化,那么得到的不是指向同一个元素的迭代器,但是我在gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04) 上,不能用普通迭代器给反向迭代器赋值(这里指等号赋值)。

这里必须采用圆括号初始化才可以。赋值本人还不会,有大神会就给我回复一个,谢谢!!!

而反向迭代器给普通迭代器赋值,必须通过反向迭代器的成员函数base()才能实现


 

猜你喜欢

转载自blog.csdn.net/digitalkee/article/details/112121246