前言
前面我们分析了迭代器的五类, 而迭代器所指向对象的型别被称为value type
. 传入参数的类型可以通过编译器自行推断出来, 但是如果是函数的返回值的话, 就无法通过value type
让编译器自行推断出来了. 而traits
就解决了函数返回值类型. 同样原生指针不能内嵌型别声明,所以内嵌型别在这里不适用, 迭代器无法表示原生指针(int *, char *等称为原生指针). 这个问题就通过traits
偏特化技术解决的. 这一篇我们就主要探讨traits
是怎么实现这些没有能解决的问题.
iterator_traits结构
iterator_traits
结构体就是使用typename
对参数类型的提取(萃取), 并且对参数类型在进行一次命名, 看上去对参数类型的使用有了一层间接性. 以下就是它的定义.
template <class 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; // 迭代器所指对象的类型引用
};
在五类迭代器对模板对象的类型重新定义一次. 这里提取(萃取)出来的参数类型名都是统一的, 也就说明每个要使用traits
编程的类必须以此类型名为标准, 而且需要自己对类定义这些类型名.
上面的traits
结构体并没有对原生指针做处理, 所以还要为特化, 偏特化版本(即原生指针)做统一. 以下便是iterator_traits 的特化和偏特化实现
// 针对原生指针 T* 生成的 traits 偏特化
template <class T>
struct iterator_traits<T*> {
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef ptrdiff_t difference_type