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;
}