iterator模式:提供一种方法,使之能够依序寻访某个容器所含的各个元素,而又无需暴露该聚合物内部表述方式。
-
迭代器是一种smart pointer
迭代器是一种行为像指针的对象,指针最常见的内容是 dereference 和 member access(成员访问)
迭代器最重要的变成工作就是对 operator* 和operator-> 进行重载
-
迭代器相应的型别
在算法运用迭代器时,会用到迭代器的相应型别。算法有必要声明一个变量,以"迭代器所指对象的型别"为型别(要推导出 *iter 的型别)。利用function template 的参数推导机制。
要推断出 *iter 由于func_impl() 是一个 function template,一旦被调用,编译期会自动进行 template参数推导,于是导出型别T。
-
Traits 编程技法
"template参数推导机制"推而导之的只是参数,无法推导函数的返回值型别。
可以在类中内嵌型别声明
typedef T value_type;
使用的时候返回值为
Template<class I>
typename I::value_type
迭代器所指对象的型别,称为该迭代器的value type。
func 的返回类型必须加上关键词 typename, 因为 T 是一个template参数,它再编译器具体现化之前,编辑器对T一无所知,换句话说,编译器此时并不知道 MyTter<T>::value_ype 代表的是一个型别或是一个member function 或是一个data member。关键词 typename 的用以在于告诉编译器这是一个型别,如此才能顺利通过编译。
并不是所有迭代器都是class type,原生指针就不是,如果不是class type,就无法为他内嵌型别。
-
partial specialization 偏特化的意义
如果class template 拥有一个以上的template 参数,我们可以针对其中某个(并非全部)template参数进行特化工作。换句话说,我们可以在泛化设计中提供一个特化版本。
partial specializtion的定义是"针对任何template参数更进一步的条件限制所设计出来的一个特化版本"
有了这项利器,就可以解决内嵌型别未能解决的问题。
这个所谓的traits的意义是,如果I定义有自己的value type, 那么通过这个traits的作用,萃取出来的value_type 就是 I::value type
最常用到的迭代器相应型别有物种 value type, difference type, pointer, referrence, interator catoagory
-
value type
value type是指迭代器所指对象的型别,任何一个打算与STL算法有完美搭配的class,都应该有自己的value type。
-
difference type
difference type表示两个迭代器之间的距离,因此它可以用来表示一个容器的最大容量。如果泛型算法提供一个计数功能,其传回值就是一个difference type。
针对相应型别difference type, traits 的如下两个特化版本,以C++内建的ptrdiff_t(<cstddef>头文件)作为原生指针的 difference type。
-
Reference type
迭代器分两种: 不允许改变所指之对象内容称为 constant iterators,例如const int * pic, 允许改变所指对象内容称为mutable iterators。当我们对一个mutable iterators 进行提领操作时,不应该获得一个右值,因为右值不能进行赋值操作。
在C++中,如果要传回左值,都是以by reference 方式进行的,当p 是一个 mutable iterator 时,如果其value type是T,那么 *p 的型别应该是 T&。
-
Pointer type
传回一个左值,令他代表p所指之物是可能的,那么传回一个左值,令它代表所指之物的地址也可以.
传回一个pointer, 指向迭代器所指之物。
Item& 便是 listiter 的 reference type, Item* 便是其 pointer type
把这两个型别分别加入traits
-
Iterator_category
根据移动特性与施行操作,迭代器被分为五类
- Input iterator : 这种迭代器所指的对象,不允许外界改变(read only)
- Output iterator: write only
- Forward iterator: 允许写入型算法在这种迭代器所形成的区间进行读写操作
- Bidirectional iterator: 可双向移动,某些算法需要逆向走访某个迭代器区间
-
Random access iterator: 前四种迭代器都只提供一部分指针算术能力(前三种 operator++ 第四种加上 operator--) 第五中覆盖所有指针算术能力 p+n p-n p[n] p1 - p2 p1<p2
箭头表示概念(concept)和强化(refinement)的关系
-
Iterator 的保证
STL提供了一个iterators class 如下
如果每个新设计的迭代器都继承自它,就可以保证STL所需之规范
Iterator class 不含任何成员,只是单纯定义型别,所以继承它不会招致任何额外的负担,由于后三个参数有默认值,新的迭代器只需提供前两个参数