1. 算法引出 Iterator Traits
- 容器使用算法操作的时候,算法会想要知道 iterator 的某些属性
- 以 rotate算法 举例
- 第一个想要的 traits 是 iterator 的 category,也就是 iterator 的移动性质,如是否可以++,--,以及 +=,以便采取最佳的操作方式
- 第二个想要的 traits 是 iterator 的 difference_type,也就是容器中两个 iterator 的距离
- 第三个想要的 traits 是 iterator 的 value type,就是容器中的元素类型,iterator 所指向的元素的类型
- 还有两个 C++ 设计了但从未被使用的,即没有算法提问这两个问题,分别是 reference 和 pointer
- 这五种类型成为 iterator associated type ,iterator 相关类型
2. iterator 必须提供的五种 associated type
- 2.9 和 4.9 都提供了 五种
-
- iterator_category 迭代器移动性质,可否向前向后,跳跃
- value_type 迭代器所指向的元素数据类型
- pointer 指针
- reference 引用
- difference_type 迭代器之间的距离,采用的数据类型是 C++ 标准库中的 ptrdiff_t 应该是unsigned long
- 算法提问
-
- 算法传入参数为 iterator
- 如 I : : iterator_categroy 就是算法提问,要获取 iterator_categroy
3. iterator traits(萃取器)
- 算法可以直接这样提问并获取这几个参数,为什么要设计traits呢
- 如果 iterator 并不是 class,而是 指针,指针可以看作是退化的 iterator,iterator 是泛化的指针
- 因为有的容器可以直接使用指针作为iterator
- 退化的指针无法通过 I : : iterator_category 这种方式来回答问题,所以需要萃取机,加一个中间层
- class 都有能力定义自己的 associated types,而 native pointer 就不可以,所以交给萃取机来分辨,并处理
- 利用了偏特化,泛化版本是针对 iterator 的,可以直接通过 I : : 取出要用的 associated type
- 而 T* 、const T* 则采用偏特化,直接得到 value type 就是 T
- 注意 const T* 的 value type 也是 T,因为如果是 const T,那么 value 后续则无法被赋值,无法被赋值的变量就没有意义了
- 这就是完整的 traits 实现
- 如果是 const T*,那么它的指针和引用就是 const T*,和const T&,因为他们的指向无法改变
4. 其他 traits
- 以上也是标准库中的其他traits