五种Iterator为:
- Input Iterator
- Output Iterator
- Forward Iterator
- Bidirectional Iterator
- Radom Access Iterator
一、Input Iterator
- 用于只读,并且只能读一次。重复读没有定义。x=*it,不能再次x=*it。例如:istream_iterator。重复读有危险,应该在x=*it之后,立即++it,并且测试it!=end()。例如是否读到了流的末尾。即:单遍历(Single pass)
- 定义了operator++,但是同一时间只能使用一个iterator,不能把旧的iterator暂存。例如old=it; ++it,那么old就无意义。没有定义operator--。
二、Output Iterator
- 用于只写,并且只能写一次。重复写则可能包含危险。*it=x。如果再次*it=x,则该语句可能是个危险操作。例如ostream_iterator。
- 定义了operator++(同Input Iterator)。
三、Forward Iteraotr
- 可以只读或只写,或者包含两者。可以进行多次读写。但是只定义了operator++。
- 是多遍历(Muti pass),也就是可以暂存旧的Iteraotr。old=it有意义。++it之后,old还有效。++old也有效。常用于列表、数组等容器。
- 具有同一性(Identity):Iterator p==q,那么*p==*q。
四、Bidirectional Iterator
- 同Forward Iterator。还定义了operator--。
- 值得注意:Iterator it=end(),--it必须是有意义。也就是end()返回的iterator必须是该容器的“尾节点”,不能是一个“空”iterator。例如数组类array.end()不能返回 NULL。因为许多算法需要从end()开始进行operator--(例如:反向拷贝)。Forward Iterator没有此限制,可以用一个“空”iterator作为end()。
五、Radom Access Iterator
除了含有Bidirectional Iteraotr所有的概念外,还有如下:
- 加减法:it+n、it-n
- 两个Iterator相减:int n = it2-it1
- 下标:it[n]
- 前后次序关系:it1
也就是定义了如上几个操作符。可以看做C语言的内存指针p。虽然Bidirectional Iterator能够模拟出it+n的操作,但效率太低。
五个Iterator的关系图:
六、iterator_category的作用:
所有的自定义Iterator类都必须从以上五个中的一个继承,就自动包含了iterator_category这个typedef重定义的类型。主要用于一些算法的优化重载函数中。例如:
template<class InputIteratr, class Distance>advance(InputIterator it, Distance n){__advance(it, n, iterator_traits ::iterator_category());}
iterator_traits<...>是为了适配原生指针(使用iterator_traits 特化)。__advance有许多重载版本,根据iterator_traits ::iterator_category来确定一个。