STL与泛型编程<八>:迭代器简介
来源:互联网 发布:礼品定制 知乎 编辑:程序博客网 时间:2024/05/17 23:29
总述
迭代器是一种型别(通俗的讲就是以一种类)声明如下
template <class Category, // iterator::iterator_category class T, // iterator::value_type class Distance = ptrdiff_t, // iterator::difference_type class Pointer = T*, // iterator::pointer class Reference = T& // iterator::reference > class iterator;
所有容器都定义其各自的迭代器型别(iterator types),所以不需要专门的头文件,但有的迭代器需要,如逆向迭代器,被定义在#include中,迭代器是一种“能够遍历某个序列内所有元素”的对象,它可以透过一般指针一致的接口来完成自己的工作。其主要分为以下几种,见图
input(输入)迭代器
input迭代器只能一次一个向前读取元素,按顺序一个个传回元素值。注意input迭代器只能读取元素一次,如果你复制了input迭代器,并使原input迭代器和新产生的副本都向前读取,可能会遍历到不同的值
几乎所有的迭代器都具有input迭代器的功能,一个典型的例子就是从“标准输入读取数据”,同一个值不会被读两次。常见操作见下图
注意input迭代器不提供递减运算操作符
output(输出)迭代器
output迭代器是将元素值一个个写入,也就是说,你只能一个个元素地赋新值,而且不能使用output迭代器对同一序列进行两次遍历,下图是其操作
operator/*只有在赋值语句左手边才有效,注意output迭代器无需比较,无法检验output迭代器是否写入成功,唯一可以做的就是写入,再写入,几乎所有迭代器都具有output迭代器的功能。一个典型的例子“将元素输出到标准输出设备”的迭代器;output迭代器另一个典型例子就是inserters,所谓inserters是用来将元素插入容器的一种迭代器。
forward(前向)迭代器
forward迭代器是input迭代器和output迭代器的结合,具有input迭代器的全部功能和output迭代器的部分功能,其操作如下图
为什么具有output迭代器的部分功能,见下
若是output迭代器,我们无需检查是否抵达序列尾端,便可直接写入数据,因此可以这样写
while (true){ *pos = foo(); ++pos;}
对于forward迭代器,必须在存取数据之前确保有效,否则会引发未定义的行为,因此得这么写
while (pos != col.end()){ *pos = foo(); ++pos;}
这个循环不适合output迭代器,因为output迭代器没有定义operator!=
bidirectional(双向)迭代器
双向迭代器在forward迭代器的基础上提供了回头遍历的能力,换言之,它支持递减运算符,其新增操作如下
- random access(随机存取)迭代器
random access迭代器在双向迭代器的基础上再增加随机存取能力,因此它必须提供“迭代器算术运算”,也就是说它能够加减某个偏移量,能处理距离问题,并运用比较操作符,以下迭代器支持rand access迭代器:
1. 可随机存取的迭代器(vector,deque)
2. string(字符串,string,wstring)
3. 一般array(指针)
其新增的操作如下图
见一个例子
#include <iostream>#include <vector>using namespace std;int main(void){ vector<int> col; for (int i=-3; i<=9; ++i) col.push_back(i); //只适用于随机迭代器 cout << "number/distance: " << col.end() - col.begin() << endl; vector<int>::iterator pos; for (pos=col.begin(); pos!=col.end(); ++pos) cout << *pos << ' '; cout << endl; //此操作只对random access 有效 for (int i=0; i<col.size(); ++i) cout << col.begin()[i] << ' '; cout << endl; //此操作只对random access 有效 for (pos=col.begin(); pos < col.end()-1; pos+=2) //注意这里的循环结束条件(避免未定义行为) cout << *pos << ' '; cout << endl; return 0; }
本例对lists,sets和maps无效,因为程序中标识的部分都只适用于random access迭代器。注意只有在面对random access迭代器时,才能以operator< 作为结束与否的判断准则
对于程序中最后一个循环的解释见下图
容器的迭代器类型
- vector和deque的迭代器是随机迭代器,灵活性最大,基本适用于任何一个STL算法及迭代器相关操作
- list的迭代器是双向迭代器,因此凡是用到随机迭代器的STL算法你都不能使用
- set和map的迭代器也是双向迭代器
- STL与泛型编程<八>:迭代器简介
- STL与泛型编程<十七>:STL算法简介及for_each()算法
- 泛型编程与STL
- 泛型编程与STL
- STL与泛型编程
- STL与泛型编程
- 泛型编程与STL
- 《泛型编程与stl》
- 泛型编程与STL
- 泛型编程与STL(一):iterator 迭代器
- 泛型编程与STL学习笔记之迭代器
- STL与泛型编程<九>:迭代器相关辅助函数
- STL与泛型编程<十一>:Insert(安插)迭代器
- STL与泛型编程<十二>:Stream(流)迭代器
- 泛型编程与STL核心要素
- 泛型编程与STL 读书笔记
- 泛型编程与STL之 container
- 《泛型编程与STL》读书笔记
- 不使用库函数实现字符串复制函数strCopy
- LeetCode 326 Power of Three
- Android动画一:帧动画
- 嵌入式Linux UDP通信:服务端程序
- PL/SQL Developer 工具优化
- STL与泛型编程<八>:迭代器简介
- RDF学习笔记
- eclipse 安装maven 插件
- C++11 right value
- 事件处理小案例
- CKEditor与CKFinder学习--安全的使用CKFinder与权限控制
- lua gc 优化方案
- aligned memory allocation
- Android菜鸟App开发,第一个App(第三天)