标签:
引言:
另外三种迭代器类型:
1)插入迭代器:这类迭代器与容器绑定在一起,实现在容器中插入元素的功能。
2)iostream迭代器:这类迭代器可以与输入与输出流绑定在一起,用于迭代遍历所关联的IO流。
3)反向迭代器:这类迭代器实现向后遍历,而不是向前遍历,所有的容器都定义了自己的reverse_iterator类型,由rbegin和rend成员函数返回。
上述迭代器都在iterator头文件中定义。
一、插入迭代器
前面曾经提到的back_inserter函数是一种插入器,插入器适宜用迭代器适配器,其带有一个容器参数,并生成一个迭代器,用于在指定容器中插入元素。通过插入迭代器赋值时,迭代器将会插入一个新的元素。
C++提供了三种插入迭代器,其差别在于插入元素的位置不同:
1)back_inserter:创建使用push_back实现插入的迭代器。
2)front_inserter:使用push_front实现插入。
3)inserter:使用insert实现插入操作。出了所关联的容器外,inserter还带有第二个实参:指向插入起始位置的迭代器。
1、front_inserter需要使用push_front
front_inserter的操作类似于back_inserter:该函数创建一个迭代器,调用它所关联的基础容器的push_front成员函数代替赋值操作。
deque<int> iDeq; front_inserter(iDeq) = 1; //OK vector<int> iVec; front_inserter(iVec) = 1; //Error back_inserter(iVec) = 1; //OK
只有当容器提供 push_front操作时,才能使用front_inserter。在vector或其他没有push_front运算的容器上使用front_inserter,将产生错误。
2、inserter将产生在指定位置实现插入的迭代器
inserter适配器提供更普通的插入形式。这种适配器带有两个实参:所关联的容器和指示起始插入位置的迭代器。
list<int>::iterator it = find(iList.begin(),iList.end(),42); /* *在创建 inserter 时,应指明新元素在何处插入。 *inserter 函数总是在它的迭代器实参所标明的位置前面插入新元素。 */ replace_copy(iVec.begin(),iVec.end(),inserter(iList,it),0,100);
3、inserter+容器的begin组合与 front_inserter的区别:
在使用front_inserter时,元素始终在容器的第一个元素前面插入。而使用inserter时,元素则在指定位置前面插入。
//理解下面输出的区别 list<int> ilst,ilst1,ilst2; for (list<int>::size_type index = 0; index != 4; ++index) { ilst.push_front(index); } copy(ilst.begin(),ilst.end(),front_inserter(ilst1)); copy(ilst.begin(),ilst.end(),inserter(ilst2,ilst2.begin())); cout << "iList1: " << endl; for (list<int>::iterator iter = ilst1.begin(); iter != ilst1.end(); ++iter) { cout << *iter << '\t'; } cout << endl << "iList2: " << endl; for (list<int>::iterator iter = ilst2.begin(); iter != ilst2.end(); ++iter) { cout << *iter << '\t'; } cout << endl;
【小心地雷:】
front_inserter的使用将导致元素以相反的次序出现在目标对象中!
//P349 习题11.14 void printList(const list<int> &iList) { for (list<int>::const_iterator iter = iList.begin();iter != iList.end(); ++iter) { cout << *iter << '\t'; } cout << endl; } int main() { list<int> iList; list<int> iList1,iList2,iList3; for (list<int>::size_type i = 0;i != 10; ++i) { iList.push_back(i); } cout << "iList: " << endl; printList(iList); replace_copy(iList.begin(),iList.end(),front_inserter(iList1),0,100); cout << "iList1: " << endl; printList(iList1); replace_copy(iList.begin(),iList.end(),inserter(iList2,iList2.begin()),0,100); cout << "iList2:" << endl; printList(iList2); replace_copy(iList.begin(),iList.end(),back_inserter(iList3),0,100); cout << "iList3:" << endl; printList(iList3); }
二、iostream迭代器
虽然iostream类型不是容器,但是标准库同样提供了iostream对象上使用的迭代器:istream_iterator用于读取输入流,而ostream_iterator用于写输出流。这些迭代器将它们所对应的流视为特定类型的元素序列。使用流迭代器时,可以用泛型算法从流对象中读取数据或写数据到流对象中。
iostream迭代器的构造函数 |
|
---|---|
istream_iterator<T>in(strm); |
创建从输入流strm中读取T类型对象的istream_iterator对象 |
istream_iterator<T>in; |
istream_iterator对象的超出末端迭代器 |
ostream_iterator<T>in(strm); |
创建将T类型的对象写入到输出流strm的ostream_iterator对象 |
ostream_iterator<T>in(strm,delim); |
创建将T类型的对象写入到输出流strm的ostream_iterator对象,再写入过程中使用delim作为元素的分隔符。delimit是以空字符结束的字符数组。 |
流迭代器只定义了最基本的迭代器操作:自增、解引用和赋值。此外,可比较两个istream迭代器是否相等(或不等)。而ostream迭代器则不提供比较运算
istream_iterator的操作 |
|
---|---|
it1== it2 it1!= it2 |
比较两个istream_iterator对象是否相等/不等。迭代器必须读取的是相同的类型。如果两个迭代器都是end值,则它们相等。对于两个都不指向流结束符位置的迭代器,如果它们使用同一个输入流构造,则它们也相等。 |
*it |
返回从流中读取的值 |
it-> mem |
是(*it).mem的同义词,返回从流中读取的对象的mem成员 |
++it it++ |
通过使用元素类型提供的>>操作符从输入流中获取下一个元素值,使迭代器向前移动。通常,前缀版本使迭代器再流中向前移动,并返回对加1后的迭代器的引用。而后缀版本使迭代器在流中向前移动后,返回原值 |
1、流迭代器的定义
流迭代器都是类模板:任何已定义输入操作符(>>操作符)的类型都可以定义stream_iterator。类似地,任何已定义输出操作符(<<操作符)的类型也可定义ostream_iterator。
在创建流迭代器时,必须指定迭代器所读写的对象类型:
istream_iterator<int> cin_it(cin); istream_iterator<int> end_of_stream; ofstream outfile; ostream_iterator<Sales_item> cout_it(outfile," ");
【注意:】
ostream_iterator对象必须与特定的流绑定在一起。在创建istream_iterator时,可直接将它绑定到一个流上。另一种方法是在创建时不提供实参,则该迭代器指向超出末端位置。ostream_iterator不提供超出末端迭代器。
在创建ostream_iterator对象时,可提供第二个(可选的)实参,指定将元素写入输出流时使用的分隔符。分隔符必须是C风格字符串。因为它是C风格字符串,所以必须以空字符结束;否则,其行为将是未定义的。
2、istream_iterator对象上的操作
构造与流绑定在一起的istream_iterator对象时,将对迭代器定位,以便第一次对该迭代器进行解引用时即可从流中读取第一个值。
vector<int> iVec; istream_iterator<int> in_iter(cin); istream_iterator<int> eof; while (in_iter != eof) { iVec.push_back(*in_iter++); }
while循环从cin中读取 int型数据,并将读入的内容保存在iVec中。每次循环都检查in_iter是否为 eof。其中eof迭代器定义为空的istream_iterator对象,用作结束迭代器。绑在流上的迭代器在遇到文件结束或某个错误时(如输入的是字符),将等于结束迭代器的值。
//可以这样重写该<span class="wp_keywordlink" style="margin: 0px; padding: 0px; border: 0px; background: transparent;"><a target=_blank href="http://www.xuebuyuan.com/" title="程序" target="_blank" style="text-decoration: none; color: rgb(1, 150, 227);">程序</a></span> istream_iterator<int> in_iter(cin); istream_iterator<int> eof; vector<int> iVec(in_iter,eof);
这里,用一对标记元素范围的迭代器构造vector对象。这些迭代器是istream_iterator对象,这就意味着这段范围的元素是通过读取所关联的流来获得的。
C++ Primer 学习笔记_42_STL实践与分析(16)–再谈迭代器【上】
标签:
原文地址:http://blog.csdn.net/selfi_xiaowen/article/details/51334750