STL定义了5种迭代器:输入迭代器、输出迭代器、正向迭代器、双向迭代器和随机访问迭代器。如上表所示为各迭代器功能。
STL为何需要这么多迭代器呢?目的是为了在编写算法时尽可能使用要求最低的迭代器。如:find
函数可以用于任何可读取值的容器,sort
函数由于需要随机访问迭代器,所以只能用于支持这种迭代器的容器。
需要注意上面5种迭代器只是一系列的要求,而不是类型。如正向迭代器,用STL所设计的迭代器可以满足这种要求,用常规指针也能满足这种要求。
STL所提供的算法可以使用任何满足其要求的迭代器实现,在STL文献中实用术语概念(concept)
来描述这一系列的要求。
这里用STL的copy
函数来举例STL提供的部分迭代器,copy函数原型如下:
_OutputIterator copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result);
功能:将指定[__first, __last)
输入迭代器范围的数据内容复制到__result
输出迭代器位置之前。
int casts[10]= {16, 7, 2, 9, 4, 11, 8, 7, 10, 5};
std::vector<int> dice(10);
std::copy(casts, casts + 10, dice.begin()); // copy array to vector
如上所示,将指向数组的指针当作迭代器,将数组内容复制到dice
数组中。
注:需要保证dice
容器大小至少和数组casts
一样大,否则会越界写发生段错误。
#include <iterator>
...
std::ostream_iterator<int, char> out_iter(std::cout, " ");
std::copy(dice.begin(), dice.end(), out_iter);
// 屏幕输出:16 7 2 9 4 11 8 7 10 5
如上所示,如果需要将信息复制到显示器上,则STL提供了ostream_iterator
模版,其中第一个模版参数(这里为int
)指出被发送给输出流的数据类型,第二个模版参数(这里为char
)指出了输出流使用的字符类型,构造函数第一个参数(std::cout
)指出了要使用的输出流,第二个参数(" "
)指定输出流的每个数据项后显示的分隔符。
*out_iter++= 15; // works like cout<<15<<" ";
如上所示,可以像上面使用ostream_iterator
来替代cout
的流写法。
std::vector<int> vecs(10);
std::copy(std::istream_iterator<int, char>(std::cin),
std::istream_iterator<int, char>(), vecs.begin());
如上所示,还可以使用istream_iterator
将输入流数据放进vecs
中。
除了ostream_iterator
和istream_iterator
之外,头文件iterator
还提供了其它一些专用的预定义迭代器类型:reverse_iterator
、back_insert_iterator
、front_insert_iterator
和insert_iterator
。
int casts[10]= {16, 7, 2, 9, 4, 11, 8, 7, 10, 5};
std::vector<int> dice;
std::back_insert_iterator<std::vector<int> > back_iter(dice);
std::copy(casts, casts + 10, back_iter); // copy array to vector
之前用std::copy
前需要保证输出的容器足够大,这时可以用insert_iterator
相关迭代器,这样就不需要提前分配输出容器容量。