前面说过,迭代器是一个广义指针,可以对其进行指针一样的操作,不同的迭代器功能也不一样,在某些算法中,要求迭代器支持递增运算符以遍历整个容器,有的要求能够读取数据但是不能够改变数据,有的要求能够随机访问等等,为此,STL定义了五种迭代器,并且根据迭代器类型对算法进行了描述。五种迭代器类型分别为:输入迭代器、输出迭代器、正向迭代器、双向迭代器和随机访问迭代器。对于这五种迭代器,他们都可以执行解引操作,也可以进行比较。他们在概念上如同下面的描述:
输入迭代器来自容器的信息被视为输入,就像来自键盘的信息对于程序来说是输入一样,因此,输入迭代器可以被程序用来读取容器中的数据,但是不一定能修改数据,对于不会修改容器数据的算法来讲是一个好的选择。输入迭代器能够访问容器中的所有值,这是通过递增运算符实现的,但是也不能够保证第二次遍历容器时顺序不变,也不保证在输入迭代器递增后原来的值还可以被解引。基于输入迭代器的算法都应该是单向通行的,不能依赖于前一次遍历也不依赖递增前的迭代器。
总而言之:
- 输入迭代器可以被程序用来读取容器中的数据,但是不一定能修改数据
- 通过递增运算符输入迭代器能够访问容器中的所有值
- 输入迭代器是单向迭代器,可以递增但是不可以倒退
- 每次遍历的顺序不一定一样,递增后如果再递减不一定指向原来的值
指用于将信息从程序传递给容器的迭代器。它可以解引修改容器值,但是却不能够读取,cout可以修改发送到屏幕上的字符流,但是不能够读取屏幕上的内容。
因此,对于单通行只写算法可以使用输出迭代器,对于单通行只读算法可以使用输入迭代器。
正向迭代器与输入输出迭代器一致,只使用递增运算符来遍历容器,但是,它却总是按照相同的顺序来遍历容器,在迭代器递增后之前的值解引后还可以得到对应的值。对于正向迭代器,他是能够可读可写的,也可以使用const限定符来令其变为只读。
双向迭代器能够双向遍历容器,双向迭代器具有正向迭代器的所有特性,同时还支持递减运算符。
随机访问迭代器有一些算法比如说排序,插入之类的,需要直接跳到特定的位置执行操作,这就要求可以随机访问的随机访问迭代器,它具有双向迭代器的所有特性,同时添加了随机访问的操作和对用于排序的关系运算符。
比如说可以两个迭代器相减求出两个值的距离,可以迭代器与数值相加(具有交换性)求出这个值后的第n个元素,也可以迭代器减去一个值求出前面的第n个元素,并支持+=-=运算符,可以使用方括号随机访问,可以进行迭代器之间的比较。
对于如此多种类的迭代器,目的是为了 在编写算法时尽可能地使用要求最低的迭代器,并且让其适用于容器的最大区间。
可以用指针作为迭代器
copy()、ostream_iterator、istream_iteratorSTL提供了一些预定义迭代器。首先看一种用迭代器实现的算法:copy()
它的作用是将数据从一个容器复制到另一个容器中,他接受三个参数,前两个参数指定要复制的范围,最后一个迭代器指出要复制到什么位置,前两个参数最好是输入迭代器,最后一个最好是输出迭代器,这个方法将覆盖目标容器中的已有数据,同时需要确保目标容器足够大以容纳数据,因此如果不采用特殊方法不能够将数据复制到空vector数组中去。
尝试把数据复制到空的矢量数组中会出现错误:
了解了copy()方法的基本操作,现在,假设要复制信息到显示器上,如果有一个表示输出流的迭代器,就可以这样使用这个方法,STL为这种迭代器定义了ostream_iterator模板,通过包含头文件iterator可以使用这种迭代器。
#includeostream_iterator out_iter(cout," ");
看上面这个声明,它指出out_iter为一个迭代器接口,<>中的第一个参数表示被发送给输出流的数据类型,第二个参数指出输出流的数据类型,可以是char 和wchar_t 函数参数的第一个表示要使用的输出流,第二个字符串参数表示在发送给输出流的每个数据项后显示的分隔符。可以直接将匿名迭代器用作适配器然后作为参数。
这个头文件还定义了一个istream_iterator模板,使istream输入可以作为迭代器接口,它是一个输入迭代器的概念模型,用法和ostream_iterator类似:
copy(istream_iterator(cin),istream_iterator (),arr.begin());
cin表示使用cin管理的输入流,第二个参数的声明()内没有参数,表示输入失败,因此,上面的可以表示从输入流中读取知道文件结尾、类型不匹配或者其他输入故障为止。



