STL源码剖析--迭代器与traits编程技法心得笔记

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的好处是可以通过函数的形参进入哪个函数.

原文地址:https://www.cnblogs.com/2462478392Lee/p/14141387.html