Effective STL:26 - 29 迭代器

本文详细探讨了STL中四种迭代器(iterator、const_iterator、reverse_iterator和const_reverse_iterator)的特点与使用方法,并重点讲解了如何在特定情况下将const_iterator转换为iterator,以及reverse_iterator的正确使用方式。

STL提供了四种不同类型的迭代器:iteratror、const_iterator、reverse_iterator、 和const_reverse_iterator。


26.iterator优先于const_iterator、reverse_iterator、 以及const_reverse_iterator。

原因:

1.有些版本的insert函数和erase函数要求使用iterator,如果需要调用这些函数,则必须使用iterator。const和reverse型的迭代器不能满足这些函数的要求。

2.要想隐式的将一个const_iterator转换成iterator是不可能的。

3.从reverse_iterator转换过来的iterator在使用之前需要相应的调整。(base())。


结论:尽量使用iterator代替const_iterator


27.使用distance和advance将容器的const_iterator转换成iterator。

26条已经介绍了,从const_iterator到iterator不存在隐式转换。


如果一定要把const_iterator转换成iterator,可以这样(同时使用advance函数和distance函数):

IntDeque d;

ConstIter ci;

……

Iter i(d.begin());

advance(i,distance<ConstIter>(i,ci));  //这里是利用了iterator转换成const_iterator的性质,反正distance()函数只需要求出两个迭代器之间的距离。


这样i和ci就指向了容器中的相同位置了。


28正确理解由reverse_iterator的base()成员函数所产生的iterator用法。

关于reverse_iterator的一个使用方法,前面的笔记中有一个记载。

list<int> list1;  
list<int> list2;  

list1.splice(list1.end(),list2,  
	find(list2.begin(),list2.end(),5),  
	find(list2.rbegin(),list2.rend(),10).base()  
	);  
26条也介绍过,insert()函数和erase()函数不支持reverse_iterator迭代器,所以要执行插入和删除必须要通过base()函数来调用iterator版本。


如果要在一个reverse_iterator ri指定位置上插入新元素,只需在ri.base()位置查入元素即可。对于插入操作而言,ri和ri.base()是等价的。ri.base()是真正与ri对于的iterator。

如果要在一个reverse_iterator ri指定位置上删除这个元素,则需要在ri.base()前面的位置执行删除操作。对于删除操作而言,ri和ri.base()是不等价的,ri.base()不是与ri对应的iterator。

这里要反复强调一次,在某个地方插入一个元素,是在那个元素之前插入一个元素!!

#include <iostream>
#include <deque>
#include <algorithm>
#include <iterator>
using namespace std;

int main()
{
	deque<int> IntDeque;
	for(int i = 1;i <= 3; ++i)
	{
		IntDeque.push_back(i);
		IntDeque.push_front(i);
	}
	//输出: 3 2 1 1 2 3
	copy(IntDeque.begin(),IntDeque.end(),ostream_iterator<int>(cout," "));
	cout << endl;

	//现在在最后一个1的后面插入一个4 
	deque<int>::reverse_iterator it = find(IntDeque.rbegin(),IntDeque.rend(),1);
	IntDeque.insert(it.base(),4);
	//输出:3 2 1 1 4 2 3
	copy(IntDeque.begin(),IntDeque.end(),ostream_iterator<int>(cout," "));
	cout << endl;

	//删除最后一个2
	it =  find(IntDeque.rbegin(),IntDeque.rend(),2);
	IntDeque.erase((++it).base());
	//输出: 3 2 1 1 4 3
	copy(IntDeque.begin(),IntDeque.end(),ostream_iterator<int>(cout," "));
	cout << endl;

	return 0;
}<span style="color:#ff0000;">
</span>

29,对于逐个字符的输入,请考虑istreambuf_iterator。

首先要注意,这一条针对的是char类型。

对于非格式化的逐个字符输入过程,应该考虑istreambuf_iteartor,同样的对于非格式化的逐个字符输出过程,应该考虑使用ostreambuf_iterator。istreambuf_iterator不会跳过任何字符,它只是简单的取回缓冲区的下一个字符,不管它们是什么字符。

此外使用istreambuf_iterator的速度要大大快于istream_iterator。

#include <iostream>
#include <string>
#include <fstream>

using namespace std;

int main()
{
	ifstream inputFile("F://in.txt");
	string str((istreambuf_iterator<char>(inputFile)),istreambuf_iterator<char>());
	cout << str << endl;

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值