<iterator> 中定义了迭代器得使用方法,主要得模版类有:
插入迭代器
插入迭代器是一种迭代器适配器,带有一个容器参数,并生成一个迭代器,用于在指定的容器中插入元素。通过插入迭代器赋值时,迭代器将会插入一个新的元素。C++语言提供了三种插入器,其差别在于插入元素的位置不同:
back_inserter,创建使用push_back实现插入的迭代器,其使用一个对象作为实参将一个新元素插入到容器得后端
front_inserter的操作类似于back_inserter:该函数将创建一个迭代器,调用它所关联的基础容器的push_front成员函数代替赋值操作。
注意:只有当容器提供push_front操作时,才能使用front_inserter。在vector或其他没有push_front运算的容器上使用front_inserter,将产生错误。
inserter使用insert实现插入操作,inserter还带有第二个实参:指向插入起始位置的迭代器,inserter总是在它的迭代器参数所标明的位置前面插入新元素。
流迭代器
虽然iostream类型不是容器,但标准库同样提供了在iostream对象上使用的迭代
器:istream_iterator用于读取读入流,而ostream_iterator用于写输出流。这些迭代器将它们所对应的流视为特定类型的元素
序列。使用流迭代器时,可以用泛型算法从流对象中读数据(或将数据写到流对象中)。
istream_iterator<T> in(strm); |
创建从输入流strm中读取T类型对象的istream_iterator对象,strm是一个输入流 |
istream_iterator<T> in; |
istream_iterator对象的超出末端迭代器 |
ostream_iterator<T> out(strm); |
创建将T类型的对象写到输出流strm的ostream_iterator对象 |
ostream_iterator<T> out(strm, delim); |
创建将T类型的对象写到输出流strm的ostream_iterator对象,在写入过程中使用delim作为元素的分隔符。delim是以空字符结束的字符数组 |
流迭代器只定义了最基本的迭代器操作:自增、引用和赋值。此外,可比较两个istream迭代器是否相等(或不等)。而ostream迭代器则不提供比较运算。
流迭代器的限制:
(1)不可能从ostream_iterator对象读入,也不可能写到istream_iterator对象中;
(2)一旦给ostream_iterator对象赋了一个值,写入就提交了。赋值后,没有办法再改变这个值。此外,ostream_iterator对象中每个不同的值都只能正好输出一次。
(3)ostream_iterator没有->操作符。
测试:
#include <iostream>
#include <vector>
#include <iterator>
using namespace std;
int main() {
istream_iterator<int> in_iter(cin);
istream_iterator<int> eof;
//vector<int> vec(in_iter, eof); //do the same work as following loop
vector<int> vec;
while (in_iter != eof)
vec.push_back(*in_iter++); //*in_iter可以取出输入流中得元素
vector<int>::const_iterator it = vec.begin();
for(; it != vec.end(); ++it)
cout<<*it<<endl;
return 0;
}
#include <iostream>
#include <iterator>
using namespace std;
int main() {
ostream_iterator<string> out_iter(cout, ""n");
istream_iterator<string> in_iter(cin), eof;
while (in_iter != eof)
*out_iter++ = *in_iter++;
return 0;
}
反向迭代器
反向迭代器是一种反向遍历容器的迭代器。也就是,从最后一个元素到第一个元素遍历容器。反向迭代器将自增(和自减)的含义反过来了:对于反向迭代器,++运算将访问前一个元素,而--运算则访问下一个元素。
(1)反向迭代器需要使用自减操作符:标准容器上的迭代器(reverse_iterator)既支持自增运算,也支持自减运算。但是,流迭代器由于不能反向遍历流,因此流迭代器不能创建反向迭代器。
(2)可以通过reverse_iterator::base()将反向迭代器转换为普通迭代器使用,从逆序得到普通次序。
测试:
#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
using namespace std;
int main() {
string str = "this 'sentence' is a test";
cout<<str<<endl;
string::iterator it1 = find(str.begin(), str.end(), '"'');
string::iterator it2 = find(++it1, str.end(), '"'');
cout<<string(it1, it2)<<endl;
string::reverse_iterator rit1 = find(str.rbegin(), str.rend(), '"'');
string::reverse_iterator rit2 = find(++rit1, str.rend(), '"'');
cout<<string(rit1, rit2)<<endl;
cout<<string(rit2.base(), rit1.base())<<endl;
getchar();
return 0;
}
不同的迭代器支持不同的操作集,而各种算法也要求相应的迭代器具有最小的操作集。因此,可以将算法的迭代器分为下面五类:
输入迭代器
(input iterator) |
读,不能写。支持的操作集:==, !=, 前缀++, 后缀++, *, ->。例如,find, accumulate算法要求这类迭代器。 |
输出迭代器
(output iterator) |
写,不能读。支持的操作集:前缀++, 后缀++, *(只能出现在赋值运算的左操作数上)。推出迭代器要求每个迭代器必须正好写入一次。例如,ostream_iterator是输出迭代器,copy算法使用这类迭代器。 |
前向迭代器(forward iterator) |
读和写,支持输入迭代器和输出迭代器提供的所有操作,还支持对同一个元素的多次读写。例如,replace算法需要这种迭代器。 |
双向迭代器(bidirectional iterator) |
读和写,除了支持前向迭代器的所有操作,还支持前缀--和后缀--,即支持双向遍历容器。例如,reverse算法要求这类迭代器。标准库容器中提供的迭代器都至少达到双向迭代器的要求。 |
随机访问迭代器(random-access iterator) |
读和写。提供在常量时间内访问容器任意位置的功能。支持完整的迭代器操作集:1)关系运算:==, !=, <, <=, >,
>=;2)算术运算:it + n, it - n, it += n, it -= n以及it1 -
it2;3)下标运算:it[n],等价于*(it + n)。需要随机访问迭代器的泛型算法包括sort算法。例如,vector, deque,
string迭代器是随机访问迭代器,用作访问内置数组元素的指针也是随机访问迭代器。 |
除了输出迭代器,其他类别的迭代器形成了一个层次结构:需要低级类别迭代器的地方,可使用任意一种更高级的迭代器。例如,对于需要输入迭代器的算法,可传
递前向、双向或随机访问迭代器调用该算法。而反之则不行。注意:向算法传递无效的迭代器类别所引起的错误,无法保证会在编译时被捕获到。
map, set, list类型提供双向迭代器,而string,
vector和deque容器上定义的迭代器都是随机访问迭代器,用作访问内置数组元素的指针也是随机访问迭代器。istream_iterator是输
入迭代器,ostream_iterator是输出迭代器。
另外,虽然map和set类型提供双向迭代器,但关联容器只能使用这部分算法的一个子集。因为关联容器的键是const对象。因此,关联容器不能使用任何
写序列元素的算法。只能使用与关联容器绑在一起的迭代器来提供用于读操作的实参。因此,在处理算法时,最好将关联容器上的迭代器视为支持自减运算的输入迭
代器,而不是完整的双向迭代器。
posted on 2010-08-27 15:55
何克勤 阅读(1059)
评论(0) 编辑 收藏 所属分类:
C/C++