http://www.cplusplus.com/reference/iterator/
一、每个标准容器类都提供四种迭代器类型,四种迭代器类型,不是迭代器:iterator,const_iterator,reverse_iterator和const_reverse_iterator
template <class Category, class T, class Distance = ptrdiff_t,
class Pointer = T*, class Reference = T&>
struct iterator {
typedef T value_type;
typedef Distance difference_type;
typedef Pointer pointer;
typedef Reference reference;
typedef Category iterator_category;
};
template <class Iterator> class reverse_iterator;
1. 支持的隐式转换:
- iterator到const_iterator
- iterator到reverse_iterator
- reverse_iterator到const_reverse_iterator
2. base成员函数转换:
- reverse_iterator 到 iterator
- const_reverse_iterator 到 const_iterator
- reverse_iterator的base成员函数返回一个“对应的”iterator的说法并不准确。对于插入操作而言,的确如此;但是对于删除操作,并非如此。
v.erase((++ri).base()); 如果是删除动作,需要将reverse_iterator先增加,再调用base成员函数。 - 下面这种方式居然也编译过了,与书中所述不一致。
- #include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<int> v;
vector<int>::reverse_iterator ri =
find(v.rbegin(), v.rend(), 3); // 同上,ri指向3
v.erase(--ri.base());
}
- reverse_iterator的base成员函数返回一个“对应的”iterator的说法并不准确。对于插入操作而言,的确如此;但是对于删除操作,并非如此。
- const_iterator到iterator:
- 要得到与const_iterator指向同一位置的iterator,首先将iterator指向容器的起始位置,然后把它向前移到和const_iterator距离容器起始位置的偏移量(即distance<ConstIter>(i, ci))一样的位置即可!
- #include <iostream>
#include <deque>
using namespace std;
typedef deque<int> IntDeque; // 和以前一样
typedef IntDeque::iterator Iter;
typedef IntDeque::const_iterator ConstIter;
int main()
{
IntDeque d;
d.push_back(1);
d.push_back(2);
Iter i(d.begin()); // 初始化i为d.begin()
ConstIter ci = (i+1);
cout << *ci <<endl;
advance(i, distance<ConstIter>(i, ci));
cout << *i << endl;
return 0;
}
4. 要点:
- 有些容器成员函数只接受iterator作为参数,尽量用iterator代替const_iterator,reverse_iterator和const_reverse_iterator。如insert和erase。
- 减少混用不同类型的迭代器的机会;如果混用了,则使用static_cast将iterator转换为其他类型,不使用默认转换。
二、函数:
template<class InputIterator>
typename iterator_traits<InputIterator>::difference_type
distance (InputIterator first, InputIterator last);
template <class InputIterator, class Distance>
void advance (InputIterator& i, Distance n);
三、插入迭代器:重载了=运算符,对其进行赋值=操作,会触发push_front,push_back,insert操作,可增加容器大小!而其他迭代器没有此功能,只能更新!
1. back_insert_iterator --- 通过back_inserter 函数获得;向容器尾部插入一个。
template <class Container>
back_insert_iterator<Container> back_inserter (Container& x);
2. front_insert_iterator --- 向容器头部插入一个。
3. insert_iterator --- 初始化时指定位置,向容器指定位置插入。
四、输入输出迭代器:
- istream_iterator
- ostream_iterator --- 重定义操作运算符=,输出。
- istreambuf_iterator
- ostreambuf_iterator --- 重定义操作运算符=
- 把一个文本文件拷贝到一个字符串对象中,使用istreambuf_iterator比使用istream_iterator快得多。
ifstream inputFile("interestingData.txt");string fileData((istreambuf_iterator<char>(inputFile)),istreambuf_iterator<char>());
或者
ifstream inputFile("interestingData.txt");string fileData;fileData.reserve(2048);fileData.assign((istreambuf_iterator<char>(inputFile)), istreambuf_iterator<char>());
以上迭代器都可以归为以下五种类型的迭代器:
- Input iterators --- istream_iterator,istreambuf_iterator
- output iterators --- ostream_iterator,ostreambuf_iterator,插入迭代器
- Forward iterators
- Bidirectional iterators ------- 所有标准容器都至少支持此级别的迭代器!如list,map
- Random access iterators --- 如vector,string