首先引用书上的一句话: STL中心思想是把数据容器和算法分开。
迭代器是两者结合的关键,那么我们算法当然是通过迭代器来对容器操作了,但是我们在算法中经常需要得到迭代器的相应型别:比如 迭代器说指向的类型。那么怎么得到这些类型呢,当然你可以通过函数模板实现部分功能,也可以通过在迭代器里自定义这些型别。比如:
template<...........>
struct iterator
{
typedef T value_type;
.........
};
通过这种方式来直接得到类型,但是如果我们在给某个算法函数提供的是 指针而不是迭代器怎么办呢,指针不是class 我们当然不能在里面定义这些类别。
这个时候就有了 traits思想了,我们可以通过一个类模板,得到无论是指针还是迭代器的相应型别:
template<typename T>
struct iterator_traits
{
typedef T::value_type value_type;
..........
};
然后利用模板偏特例化:
template<typename T>
struct iterator_traits<T*>
{
typedef T value_type;
.................
};
这样就可以 统一的抽取出 相应型别了,而不用在乎到底是指针的还是迭代器的。
代码如下:
最后来看:
typedef typename T::iterator_category iterator_category;
这一句代码。
这句代码是提供获得 迭代器的类型,迭代器类型分为5类:
input iterator
output iterator
forward iterator
bidirectional iterator
random access iterator
之所以要提供识别迭代器类型,是因为不同的迭代器类型对应了不同的元素访问方式,那么也对应着算法的效率。
如果你不提供这些类型,那么你只有通过 ++ --来依次访问元素了,这个对于像指针这种随机访问的是不公平的,因为指针可以直接+n,如果你一次一次的+1这样操作肯定效率是会很低的,所以这里就有必要提供迭代器的类型。