STL的中心思想在于:将数据容器和算法分开,彼此独立设计,最后再以一贴胶着剂将它们撮合在一起.
其中的胶着剂就是迭代器啦.
如何设计出一个优秀的迭代器呢.
迭代器可以说是一种smart pointer(智能指针).
其中介绍到了一个很重要的设计--traits
什么是traits呢,我个人觉得STL源码剖析这本书讲的有点晦涩难懂,但查阅了不少博客也是弄懂了这个traits技巧
书中说,traits就是一个萃取机.什么是萃取机,举个例子.
例如我们要写一个交换函数
template <class T1, class T2, class T> inline void __iter_swap(T1 a, T2 b, T*) { T tmp = *a; *a = *b; *b = tmp; }
在这里我们需要传递T的类别,这样就比较麻烦,但是如果我们改为这样.
template<class T> struct __list_iterator { typedef T value_type; …. }; template <class T1, class T2> inline void myiter_swap(T1 a, T2 b) { typename T1::value_type tmp = *a; *a = *b; *b = tmp; }
改成这样以后只要T1,T2是迭代器类型就能通过访问value创建T1的value_type就可以得到.
但有可能会产生疑问,直接T1创建不就好了,但是如果此时我们需要返回类型呢,是不是就不能达到目的了.所以需要内嵌型别.
所以说traits是一台萃取机,萃取迭代器特性型别,多一层间接性,便于拥有特化版本.
对于STL迭代器而言,还有迭代器分类,指针,引用,两个迭代器之间距离的类型
template<typename _Iterator> struct iterator_traits { typedef typename _Iterator::iterator_category iterator_category;//迭代器分类 typedef typename _Iterator::value_type value_type;//对象型别 typedef typename _Iterator::difference_type difference_type;//引用 typedef typename _Iterator::pointer pointer;//指针 typedef typename _Iterator::reference reference;//两个迭代器距离 };
其中typename加到这里的意思是使用嵌套依赖类型,也就是告诉编译器,typename后面的字符串是一个类型名称,而不是成员函数或字符串.
防止是静态成员或静态成员函数不能通过编译.
其中两个迭代器距离一般为ptrdiff_t类型,为signed整型,而size_t是unsigned.
对于迭代器的相应型别(value_type)有五类:
1. Input Iterator 这种类型的迭代器不允许外界改变,是唯读的。
2. Output Iterator 是唯写的。
3. Forard Iterator 可以读写,但它只能向前移动。
4. Bidirectional Iterator 可以读写,可以前后移动。
每种迭代器对应的__advance函数就不同.这里就不一样介绍,每种类型对应一种函数.
最后介绍了一个__type__traits
也就是里面写了一些其他的型别来定义是__true_type还是__false_type,其中__true_type和__false_type是两个空的结构体
比用bool的好处是可以通过函数的形参进入哪个函数.