1,因为Iterator要模拟指针,STL中除了vector和array中的Iterator之外,其他容器的指针都是一个类,因为Iterator需要模拟指针,又因为指针需要大量的+-*/操作,因此Iterator里面必然具有大量的运算符重载。
2,Iterator_traits的作用是把迭代器的特征萃取出来。例如Iterator_traits<_Iter>::iterator_category()就会萃取出迭代器的分类,迭代器的分类是,有的迭代器只能向前走,有的迭代器可以向后走,有的可以加加,有的可以减减,有的可以跳着走。
Iterator_traits<_Iter>::value_type就可以萃取出迭代器所指向的数据的类型;
Iterator_traits<_Iter>::difference_type就可以萃取出两个迭代器之间的距离应该y用什么类型来表示,这个类型就是difference_type
3,Iterator必须提供的5种associated types
typedef bidirecyional_iterator_tag iterator_category; //(1)
迭代器的类型有5种,只读型、只写型、读写型、双向运动型、随机运动型。之所以会有这个类别,是因为STL把高效放在首位,当迭代器是随机运动型的时候,就不会调用低效类型迭代器的内容。几个例子,执行迭代器的+n操作,随机运动型迭代器完成这个操作只需要O(1)的时间复杂度,而其他类型的需要O(n)的时间复杂度。所有算法在执行类似操作的时候会先萃取迭代器的类型来调用对应的函数谋取最高的效率。
typedef T value_type; //(2)
算法可能需要建议迭代器所指向的数据类型的变量,所以需要向迭代器提问value_type。
typedef Ptr pointer; //(3)
算法可能需要建议迭代器所指向的数据类型的指针,所以需要向迭代器提问pointer。
typedef Ref reference; //(4)
算法可能需要建议迭代器所指向的数据类型的引用,所以需要向迭代器提问reference。
typedef ptrdiff_t difference_type; //(5)
用来存放两个迭代器的距离,小编认为存放的是当前迭代器到容器开始迭代器的距离。可以用此来计算两个迭代器的距离。
这五种associated types是为了回答算法的提问,其中第4个和第3个在STL中未被使用,其他的三种的作用在第2问中已经回答。因为迭代器是算法和容器之间的桥梁,算法对容器一无所知;所以,它所需要的一切信息都必须从Iterator取得,而Iterator(由容器供应)必须能够回答算法的所有提问,才能搭配该算法的所有操作。
如果iterator不是class的时候,,即是native pointer的时候,就需要使用traits了,当Iterator是class的时候,是不需要使用traits的。
4,这个traits机器必须有能力分辨出它所获取的Iterator是(1)class iterator或是(2)native pointer(指针,一种退化的迭代器) to T。利用partial specialization(偏特化) 可达到目标。
注意偏特化语法的含义,和重载差不多。下面是traits的全部定义:
5,STL中五种迭代器分类,容器中的迭代器分类是下面类的对象
struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag{} : public input_iterator_tag{};
struct bidirectional_iterator_tag{} : public forward_iterator_tag{};
struct random_access_iterator_tag{} : public bidirectional_iterator_tag{};
在迭代器的分类中,istream_iterator和ostream_iterator比较特殊,严格来讲应该叫做适配器,但是在源代码中定义istream_iterator的分类属于input_iterator_tag ,ostream_iterator的分类属于output_iterator_tag 。算不同类型的迭代器对算法效率的影响是不同的。
6,std::iterator
为了符合规范,任何迭代器都应该提供五个内嵌相应类型,以利于traits萃取。否则便是自别于整个STL架构,可能无法与其他STL组件顺利搭配。然而写代码难免忘记,谁也不能保证不会有粗心大意的时候。STL提供了一个Iterator class,如果每个新设计的迭代器都继承于它,就可保证符合STL,所需要的规范。
template <typename Ctategory, typename T, typename Distance = ptrdiff_t, typename Pointer = T*, typename Reference = T&>
struct iterator}{...}