四、泛型算法中使用迭代器
1、插入迭代器
1.1 back_inserter,创建使用 push_back 实现插入的迭代器。
1.2 front_inserter,使用 push_front 实现插入。该函数将创建一个迭代器,调用它所关联的基础容器的 push_front 成员函数代替赋值操作。只有当容器提供 push_front 操作时,才能使用 front_inserter。在 vector 或其他没有 push_front 运算的容器上使用 front_inserter,将产生错误。
1.3 inserter,使用 insert 实现插入操作。这种适配器带有两个实参:所关联的容器和指示起始插入位置的迭代器。
// position an iterator into ilst
list<int>::iterator it =
find (ilst.begin(), ilst.end(), 42);
// insert replaced copies of ivec at that point in ilst
replace_copy (ivec.begin(), ivec.end(),
inserter (ilst, it), 100, 0);
1.4 也许我们会认为可使用 inserter 和容器的 begin 迭代器来模拟 front_inserter 的效果。然而,inserter 的行为与 front_inserter 的有很大差别。在使用 front_inserter 时,元素始终在容器的第一个元素前面插入。而使用 inserter 时,元素则在指定位置前面插入。即使此指定位置初始化为容器中的第一个元素,但是,一旦在该位置前插入一个新元素后,插入位置就不再是容器的首元素了:
list<int> ilst, ilst2, ilst3;
// after this loop ilst contains: 3 2 1 0
for (list<int>::size_type i = 0; i != 4; ++i)
ilst.push_front(i);
// after copy ilst2 contains: 0 1 2 3
copy (ilst.begin(), ilst.end(), front_inserter(ilst2));
// after copy, ilst3 contains: 3 2 1 0
copy (ilst.begin(), ilst.end(), inserter (ilst3, ilst3.begin()));
2、iostream 迭代器
虽然 iostream 类型不是容器,但标准库同样提供了在 iostream 对象上使用的迭代器: istream_iterator用于读取输入流,而ostream_iterator则用于写输出流。这些迭代器将它们所对应的流视为特定类型的元素序列。使用流迭代器时,可以用泛型算法从流对象中读数据(或将数据写到流对象中)。
istream_iterator<int> in_iter(cin); // read ints from cin
istream_iterator<int> eof; // istream "end" iterator
// read until end of file, storing what was read in vec
while (in_iter != eof)
// increment advances the stream to the next value
// dereference reads next value from the istream
vec.push_back(*in_iter++);
2.2 可使用 ostream_iterator 对象将一个值序列写入流中,其操作的过程与使用迭代器将一组值逐个赋给容器中的元素相同:
// write one string per line to the standard output
ostream_iterator<string> out_iter(cout, "\n");
// read strings from standard input and the end iterator
istream_iterator<string> in_iter(cin), eof;
// read until eof and write what was read to the standard output
while (in_iter != eof)
// write value of in_iter to standard output
// and then increment the iterator to get the next value from cin
*out_iter++ = *in_iter++;
2.3 流迭代器d的几个重要限制:
不可能从 ostream_iterator 对象读入,也不可能写到 istream_iterator 对象中。
一旦给 ostream_iterator 对象赋了一个值,写入就提交了。赋值后,没有办法再改变这个值。此外,ostream_iterator 对象中每个不同的值都只能正好输出一次。
ostream_iterator 没有 -> 操作符。
3、反向迭代器
反向迭代器是一种反向遍历容器的迭代器。也就是,从最后一个元素到第一个元素遍历容器。反向迭代器将自增(和自减)的含义反过来了:对于反向迭代器,++ 运算将访问前一个元素,而 -- 运算则访问下一个元素。
// reverse iterator of vector from back to front
vector<int>::reverse_iterator r_iter;
for (r_iter = vec.rbegin(); // binds r_iter to last element
r_iter != vec.rend(); // rend refers 1 before 1st element
++r_iter) // decrements iterator one element
cout << *r_iter << endl; // prints 9,8,7,...0
4、const 迭代器
在之前使用 find 的程序中,我们将 result 定义为 const_iterator 类型。这样做是因为我们不希望使用这个迭代器来修改容器中的元素。find_first_of程序中也不打算改变容器内的任何元素,但是它却使用了普通的非 const 迭代器来保存 find_first_of 的返回值。
原因是,在第二个例子中,程序将迭代器用作 find_first_of 的实参:
find_first_of(it, roster1.end(), roster2.begin(), roster2.end())
该函数调用的输入范围由 it 和调用 roster1.end() 返回的迭代器指定。算法要求用于指定范围的两个迭代器必须具有完全一样的类型。roster1.end() 返回的迭代器依赖于 roster1 的类型。如果该容器是 const 对象,则返回的迭代器是 const_iterator 类型;否则,就是普通的 iterator 类型。在这个程序中,roster1 不是 const 对象,因而 end 返回的只是一个普通的迭代器。
5、迭代器分类
Input iterator(输入迭代器) 读,不能写;只支持自增运算
Output iterator(输出迭代器) 写,不能读;只支持自增运算
Forward iterator(前向迭代器) 读和写;只支持自增运算
Bidirectional iterator(双向迭代器) 读和写;支持自增和自减运算
Random access iterator(随机访问迭代器) 读和写;支持完整的迭代器算术运算