Stl源码剖析 第三章 iterator摘要

时间:2023-08-27 11:48:56

1. Stl的设计思想是: 将数据容器和算法分开,彼此独立设计,最后再以一贴胶合剂将它们撮合在一起,这个胶合剂就是迭代器。

2. 从3.2节迭代器的实现可知,如果要设计一个与容器分离实现的迭代器,会暴露太多容器实现的细节,也就是说,要设计出针对某个容器的迭代器,必须对容器的实现细节非常了解,

所以就将容器的实现细节交给容器设计者,专属迭代器的实现成为容器的一部分,所以每个Stl容器都有提供专属的迭代器。

3. 迭代器是一种行为类似指针的对象,而指针的各种行为中最常见也最重要的便是内容提领和成员访问,因此,迭代器最重要的编程工作就是对 operator* 和 operator-> 进行重载。

4. 函数 template参数推导机制只能推导参数,无法推导函数返回值的类型,为了解决这个问题,迭代器类要使用 typedef类型定义关键字,将其模板类型定义为一个固定的名字(value_type),

然后函数返回值写成 typename T::value_type,即可告知编译器函数返回值是一个模板类型。 但这有一个局限,如果函数参数,即这个迭代器不是类类型,而是普通指针,typename T::value_type就没用了。

解决办法,偏特化:对template参数再进行特化,即模板的模板。 具体实现是实现一个通用类,去萃取模板参数的类型。

template <class I>
struct iterator_traits
{
typedef typename I:value_type value_type;
};

如果迭代器类I有实现自己的value_type,即可萃取出来。

对于普通指针,例如 int* 和 const int*  则要实现特化版本,如下:

  template <class T>
struct iterator_traits<T*> //T* can trait int*
{
typedef T value_type;
} template <class T>
struct iterator_traits<const T*> //const T* can trait const int*
{
typedef T value_type;
}

所以关键是这个 iterator_traits,既可萃取迭代器类的value_type, 又可以萃取普通指针的类型。

5. 每个迭代器要实现5种 typedef, 这个是根据STL算法实现而做出的结论:

1). iterator_category(迭代器类型,5选1)

2). value_type 所指向对象类型。 typedef T value_type    |     typedef Iterator<T> value_type

3). difference_type 表示两个迭代器距离的类型,一般是 ptrdiff_t。

4). pointer 所指向元素的指针类型   ==>  typedef T* pointer |  typedef Iterator<T>* pointer

5). reference 所指向元素的引用类型   ==>  typedef T& reference  |  typedef Iterator<T>& reference

其实迭代器类的typedef定义和普通指针的偏特化的typedef定义是类似的。

对于iterator_category,是用class来定义的,虽然class没有内容,不仅可以促成重载机制的成功运作,另一个好处是,通过继承,可以不必再写“单纯只做传递调用”(if else)的函数。

每个迭代器只需要形似:

typedef random_access_iterator_tag:: iterator_category 即可定义自己的迭代器类型。

算法在根据迭代器重载多个实现特化版本的时候,最后一个参数就是其中一个iterator_category class的类型。

6. stl提供了一个iterator class定义,自己若是实现了一个容器,迭代器只需要继承这个iterator,重新定义Category 和 valye_type即可。

总结:

  设计适当的关联类型(以上5种), 是迭代器本身的责任。设计适当的迭代器,则是容器的责任。 因为只有容器设计者才知道该设计出怎样的迭代器来访问自己,并执行迭代器应有的各种行为(++, --, *, ->)。 因此算法可以完全

独立于容器和迭代器自行设计,对外提供迭代器参数接口即可。

traits编程技法大量运用于STL实现品种,它利用“内嵌型别”的编程技巧与编译器的template参数推导功能,增强C++未能提供的关于型别认证方面的能力,弥补了C++不为强型别语言的遗憾。了解traits编程技法,就象获得“芝麻开门”的口诀一样,从此

得以一窥STL源代码的奥秘。