一、迭代器
迭代器(iterator):扮演容器与算法之间的胶合剂,是所谓的“泛型指针”。
迭代器模式:提供一种方法,使之能够依序寻访某个聚合物(容器)所含的各个元素,而又无需暴露该聚合物的内部表达方式。
STL的中心思想在于:将数据容器和算法分开,彼此独立设计,最后再以一贴胶着剂(iterator)将它们撮合在一起。
迭代器iterator 提供了一种一般化的方法对顺序或关联容器类型中的每个元素进行连续访问。例如,假设iter为任意容器类型的一个iterator,则++iter 表示向前移动迭代器使其指向容器的下一个元素,而*iter 返回iterator 指向元素的值,每种容器类型都提供一个begin()和一个end()成员函数。
1 begin()返回一个iterator 它指向容器的第一个元素 2 end()返回一个iterator 它指向容器的末元素的下一个位置
迭代器类型 | 说明 |
输入 |
从容器中读取元素。输入迭代器只能一次读入一个元素向前移动,输入迭代器只支持一遍算法, 同一个输入迭代器不能两遍遍历一个序列 |
输出 |
向容器中写入元素。输出迭代器只能一次一个元素向前移动。输出迭代器只支持一遍算法, 统一输出迭代器不能两次遍历一个序列 |
正向 | 组合输入迭代器和输出迭代器的功能,并保留在容器中的位置 |
双向 | 组合正向迭代器和逆向迭代器的功能,支持多遍算法 |
随机访问 | 组合双向迭代器的功能与直接访问容器中任何元素的功能,即可向前向后跳过任意个元素 |
Input Iterator只能逐元素的向前遍历,而且对元素是只读的,只能读取元素一次。通常这种情况发生在从标准输入设备(通常是键盘)读取数据时。
1 *iter: 只读访问对应的元素 2 iter->member: 只读访问对应元素的成员 3 ++iter: 向前遍历一步(返回最新的位置) 4 iter++: 向前遍历一步(返回原先的位置) 5 iter1 == iter2: 判断两个迭代器是否相等 6 iter1 != iter2:判断两个迭代器是否不等 7 TYPE(iter): 复制迭代器
2、Output Iterators
Output iterator跟Input Iterator相对应,只能逐元素向前遍历,而且对元素是只写的(*iter操作不能作为右值,只能作为左值),只能写入元素一次。通常这种情况发生在向标准输出设备(屏幕或者打印机)写入数据时,或者利用inserter向容器中追加新元素时。
下面是Output Iterator的可用操作列表:
1 *iter = value: 向对应的元素写入新值 2 ++iter: 向前遍历一步(返回最新的位置) 3 iter++: 向前遍历一步(返回原先的位置) 4 TYPE(iter): 复制迭代器
3、Forward Iterators
Forward Iterator是Input Iterator和Output Iterator的结合,虽然也只能逐元素向前遍历,但可以对元素进行读写操作。下面看Forward Iterator的可用操作列表:
1 *iter: 2 iter->member: 3 ++iter: 4 iter++: 5 iter1 == iter2: 6 iter1 != iter2: 7 TYPE(): 8 TYPE(iter): 9 iter1 = iter2:
跟Input Iterator和Output Iterator不同的是,Forward Iterator可以对同一元素访问多次。下面我们特别关注一下Forward Iterator和Output Iterator的区别:
1 //ok for output iterator 2 3 //error for forward iterator 4 while(true) 5 { 6 *pos = foo(); 7 ++pos; 8 }
1 while(pos != col1.end()) 2 { 3 *pos = foo(); 4 ++pos; 5 }
4、Bidirectional Iterators
双向迭代器行为特征类似于Forward Iterator,只是额外增加了一个逐元素向后遍历的能力。所以对于双向迭代器可用的操作,除了包含Forward Iterator的所有操作外,多了一组向后遍历的操作:
1 --iter: 向后遍历一步(返回最新的位置) 2 iter--: 向后遍历一步(返回原有的位置)
5、Random Access Iterators
随机访问迭代器除了有双向迭代器的能力特征外,还可以进行元素随机访问。所以对于随机访问迭代器,增加了关于“迭代器运算”的一些操作。下面是除了双向迭代器的所有操作外,额外的操作列表:
1 iter[n]: 直接访问索引为n的元素 2 iter+=n: 向前或向后(n为负数)遍历n个元素 3 iter-=n: 先后或向前(n为负数)遍历n个元素 4 iter+n: 返回当前位置后面第n个元素的iterator位置 5 n+iter: 同上 6 iter-n: 返回当前位置前面第n个元素的iterator位置 7 iter1-iter2: 返回iter1和iter2之间的距离(distance) 8 iter1<iter2: 判断iter1是否在iter2之前 9 iter1>iter2: 判断iter1是否在iter2之后 10 iter1<=iter2: 判断iter1是否不再iter2之后 11 iter1>=iter2: 判断iter1是否不再iter2之前
容器 |
支持的迭代器 |
说明 |
vector |
随机访问 |
一种随机访问的数组类型,提供了对数组元素进行快速随机访问以及在序列尾部进行快速的插入和删除操作的功能。可以再需要的时候修改其自身的大小 |
deque |
随机访问 |
一种随机访问的数组类型,提供了序列两端快速进行插入和删除操作的功能。可以再需要的时候修改其自身的大小 |
list |
双向 |
一种不支持随机访问的数组类型,插入和删除所花费的时间是固定的,与位置无关。 |
set |
双向 |
一种随机存取的容器,其关键字和数据元素是同一个值。所有元素都必须具有惟一值。 |
multiset |
双向 |
一种随机存取的容器,其关键字和数据元素是同一个值。可以包含重复的元素。 |
map |
双向 |
一种包含成对数值的容器,一个值是实际数据值,另一个是用来寻找数据的关键字。一个特定的关键字只能与一个元素关联。 |
multimap |
双向 |
一种包含成对数值的容器,一个值是实际数据值,另一个是用来寻找数据的关键字。一个关键字可以与多个数据元素关联。 |
stack |
不支持 |
适配器容器类型,用vector,deque或list对象创建了一个先进后出容器 |
queue |
不支持 |
适配器容器类型,用deque或list对象创建了一个先进先出容器 |
priority_queue |
不支持 |
适配器容器类型,用vector或deque对象创建了一个排序队列 |