迭代器我们在前面已经学习过:
1.迭代器的4个操作符重载,即移动和取值的方式;
2.迭代器的5个typedef,即iterator_traits;
下面我们将进行iterator_category的学习
1 简介
1.1 种类
一共有5种iterator_category分别为:
1、input_iterator:istream独有的迭代器。
2、output_iterator:ostream独有的迭代器。
3、forward_iterator:继承自input_iterator,单向走的迭代器,只能走一个,不能跳。如forward_list、单向list的hashtable
4、bidirectional_iterator:继承自forward_iterator,双向走的迭代器,只能走一个,不能跳。如list、rb-tree、双向list的hashtable
5、random_access_iterator:继承自bidirectional_iterator,可以跳的迭代器。如array、vector、deque。
下例表现打印了每种类型容器的迭代器类型
另一种打印方式:
1.2 output_iterator
源码:
1.3 input_iterator
源码:
2 对算法的影响
下面介绍几种算法,通过这两种算法可以了解到其巨大影响。算法的效率与迭代器的分类有巨大关系
2.1 距离:distance
先看distance函数,它要知道两个迭代器之间的距离。根据不同的迭代器种类调用两个不同(重载)的__distance函数。对于random_access_iterator,只有连续空间才有这种指针,故可以直接相减;但若是input_iterator版本,就从头一步步走到尾,看共走了多少步。返回类型为iterator_traits中的difference_type(就是表示距离)。
如上distance,这种情况在算法的实现中非常多,如果只用一步步走的方式,复杂度极大。所以,迭代器种类对算法的影响是很深远的。
2.2 前进:advance
同上例,这里出现三种分类:一步步走呢(input_iterator),往那边走呢(bidirectional_iterator),还是可以跳呢(random_access_iterator)。
当没有特殊的版本时,如forward_iterator没有特定的类型时,由于继承了input_iterator,故is a input_iterator,所以调用input_iterator版本。
2.3 复制:copy
copy函数非常简单,只需要有copy来源端的首尾迭代器,再给出copy接收端的首迭代器,只要3个参数即可完成。但实际的实现非常麻烦,会分成非常多种情况,看copy的对象是否特属于某一种更为简便的情况,因此对应很多种实现来加快其速度。
由以上内容我们可以感受到copy实现的精细程度。这里,“has trivial” 表示“不重要的”,如同复数类的拷贝构造和拷贝赋值,用默认的即可,并不重要。这种东西属于Type Traits的部分,不属于标准库的内容,后续会给出讲解。
2.4 析构:distroy
具体细节:
2.5 unique_copy
为了防止发生output和read之间的冲突,需要制造一个Output_Iterator专属版本避免这种情况。
3 算法对迭代器种类的影响
算法对迭代器种类没有要求,但由于算法是模板函数,所以对迭代器种类有所“暗示”。