博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++基础之迭代器
阅读量:7060 次
发布时间:2019-06-28

本文共 3614 字,大约阅读时间需要 12 分钟。

迭代器的分类

 

 

 

插入迭代器(insert iterator):绑定一个容器上后可以向容器中插入元素;

流迭代器(stream iterator):绑定在输入输出流中,可以遍历关联的流;

反向迭代器(reverse iterator):迭代器向后移动,标准库容器中除了forward_list外都有反向迭代器;

移动迭代器(move iterator):使用该迭代器移动其中元素;

插入迭代器(insert iterator)

back_inserter:创建一个使用push_back的迭代器;

front_inserter:创建一个使用push_front的迭代器;

inserter:创建一个使用insert的迭代器;

注意:只有容器支持push_front的情况下,才能使用front_inserter;只有容器支持push_back的情况下,才能使用back_inserter;

若it是inserter生成的插入迭代器,则*it = val;等价于it = c.insert(it,val);++it;

顾名思义back_inserter始终将元素插入到末尾,front_inserter始终将元素插入到头部。

list
lst1 = {
1,2,3,4};list
lst2,lst3;//复制lst1到lst2,每次将lst1中的元素复制插入到lst2的前面copy(lst1.cbegin(),lst1.cend(),front_inserter(lst2));//复制lst1到lst3,每次将lst1中的元素复制插入到lst3的前面copy(lst1.cbegin(),lst1.cend(),inserter(lst3,lst3.begin()));

 

流迭代器(stream iterator)

虽然iostream类型不是容器,但是标准库定义用于IO类型对象的迭代器。istream_iterator读取输入流,ostream_iterator向输出流写数据。

istream_iterator操作

可以对任何定义了输入运算符(>>运算符)的类型定义istream_iterator。

从标准输入读取数据存入到数组中:

istream_iterator
in_iter(cin);//从cin中读取数据istream_iterator
eof;//尾后迭代器vector
vec(in_iter, eof);//将输入的数据存入数组中

使用算法将输入数据求和:

istream_iterator
in_sum(cin), eof;//从cin中读取数据,尾后迭代器cout << accumulate(in_sum, eof, 0) << endl;//将输入的数据存入数组中

istream_iterator允许使用懒惰求值

当我们将istream_iterator绑定到一个流上时,并不保证迭代器立即从流中读取数据;即具体实现中可以推迟从流中读取数据。

标准库保证的是在我们第一次解引用迭代器之前,已经完成从流中读取数据的操作。

ostream_iterator操作

可以对任何定义了输出运算符(<<运算符)的类型定义ostream_iterator。

ostream_iterator
out(os);//out将类型为T的值写到输出流os中ostream_iterator
out(os,d);//out将类型为T的值写到输出流os中,每个值后面输出一个C风格的字符串d(一个字符串字面常量或一个指向空字符结尾的字符数组指针)

不允许空的或尾后的ostream_iterator

ostream_iterator
out_iter(cout," ");copy(vec.cbegin(),vec.cend(),out_iter));//输出数组vec中的所有元素,用空格隔开cout << endl;

反向迭代器(reverse iterator)

反向迭代器(reverse iterator)从容器的尾元素向首元素移动的迭代器,此时递增表示移动到前一个元素,递减表示移动到后一个元素,移动到第一个元素的前一个位置表示结束。

除了forward_list之外的容器都有反向迭代器,可以通过rbegin、rend、crbegin、crend来获得反向迭代器。可以看出,它也有const和非const两个版本。

反向输出数组的所有元素:

vector
arr = {
0,1,2,3,4,5,6,7,8,9};for(auto riter = arr.crbegin();riter != arr.crend();++riter) cout << *riter << endl;

降序排序的另一种写法:

sort(vec.rbegin(),vec.rend());

注意流迭代器不支持递减运算,因为不能在一个流中反向移动。

反向迭代器转换为普通的迭代器

string line = "FIRST,MIDDLE,LAST";auto pos = find(line.crbegin(), line.crend(), ',');//找到最后一个单词cout << string(line.crbegin(), pos) << endl;//输出TSALcout << string(pos.base(), line.cend()) << endl;//输出LAST

上面通过调用reverse_iterator的base成员函数来完成反向迭代器向普通的迭代器的转换。

注意这两者的转换,关键在于[line.crbegin(), pos)和[pos.base(), line.cend())指向line中相同的元素范围,为了实现这个pos和pos.base()必须指向相邻位置而不是相同位置。

 

移动迭代器(move iterator)

 

泛型算法对应的5中迭代器操作

输入迭代器    只读,不写;单遍扫描,只能递增

输出迭代器    只读,不写;单遍扫描,只能递增

向前迭代器    可读写;多遍扫描,只能递增

双向迭代器    可读写;多遍扫描,可递增递减

随机访问迭代器  可读写;多遍扫描,支持迭代器所有运算

C++标准指明了泛型和数值算法的每个迭代器参数的最小类别。

例如find算法要求对序列一遍扫描,对元素只读操作,因此至少需要输入迭代器;replace函数需要一对迭代器,至少是向前迭代器;replace_copy的前两个迭代器至少是向前迭代器,第三个迭代器表示目前位置,必须至少是输出迭代器。

输入迭代器(input iterator)要支持:

它只用于顺序访问,对于输入迭代器,*it++保证有效,但是,递增他可能导致其他指向流的迭代器失效,因此只能用于单遍扫描算法,例如find和accumulate。

  1. 比较两个迭代器的相等和不相等(==、!=)
  2. 迭代器的前置和后置递增运算(++)
  3. 读取元素的解引用运算(*)
  4. 箭头运算符(->)等价于解引用

输出迭代器(output iterator)要支持:

只能向输出迭代器赋值一次,且它只能用于单遍扫描算法,用作目的位置的迭代器通常是输出迭代器。例如copy的第三个迭代器。

  1. 迭代器的前置和后置递增运算(++)
  2. 读取元素的解引用运算(*)

向前迭代器(forward iterator)要支持:

可以读写元素,只能在序列中沿一个方向移动,支持所有输入迭代器和输出迭代器的操作,可以多次读写同一个元素;因此可以保存前向迭代器的状态,可以对序列多次扫描。

双向迭代器(bidirectional iterator)要支持:

可以读写元素,只能在序列中正反两个方向移动,支持所有前向迭代器的操作,还支持前置和后置递减运算符。例如reverse要求双向迭代器。

随机访问迭代器(random-access iterator)

提供在常量时间内访问序列中任意元素,支持双向迭代器的所有功能。

  1. 比较两个迭代器相对位置的关系运算符(<、>、==、!=、...)
  2. 迭代器和整数的加减运算符(++、——、+=、—=)
  3. 两个迭代器减法运算
  4. 下标运算符,和*等价

 

转载于:https://www.cnblogs.com/yeqluofwupheng/p/6799185.html

你可能感兴趣的文章
DB2性能调节工作总结
查看>>
Office 365技术支持
查看>>
浅谈(SQL Server)数据库中系统表的作用
查看>>
OSSIM中网卡设置注意事项
查看>>
Httpclient处理摘要认证
查看>>
Info-Tech:2012年SIEM市场分析
查看>>
iphone8就算是全面屏,苹果也不见得能领先同行
查看>>
.NET简谈静态事件链
查看>>
自动化运维工具Saltstack学习笔记(一)
查看>>
Linux:chattr命令和chgrp命令
查看>>
Docker技术这些应用场景,你知道吗?
查看>>
“码农”的逆袭
查看>>
VMware无法与物理机连通Could not connect Ethernet0 to virtual network "VMnet8"完美解决
查看>>
如何利用软文让你的产品广告上百度首页
查看>>
我也来说说“自学IT能走多远”
查看>>
如何通过今日头条引精准流量,学完即用
查看>>
软件项目经理新手上路13 - 给新手的建议
查看>>
简单聊聊Qos—优先级队列 PQ
查看>>
Exchange 2013部署系列之(十一)Office Web Apps部署
查看>>
[转载] 2011 ScrumGathering大会简要记录 - 周金根
查看>>