当算法传入迭代器参数的时候,算法需要迭代器的一些类型数据,所以萃取器就代替迭代器对算法做出响应
template<typename _ForwardIterator>
inline void
rotate(_ForwardIterator __first,
_ForwardIterator __middle,
_ForwardIterator __last)
{
...
std::__rotate(__first,__middle,__last,
std::_iterator_category(_first));//__rotate,是内部实现的函数
}
实际的调用需要知道迭代器的类型,所以算法需要迭代器萃取器做出回应,返回迭代器类型
template<typename _Iter>
inline typename iterator_traits<_Iter>::iterator_category
_iterator_category(const _Iter&)
{
return typename iterator_traits<_Iter>::iterator_category;
}
通过迭代器生成iterator_traits<iterator>,可以获得迭代器五个associated types
//list 的迭代器 assoatied types
template<typename _Tp>
struct _List_iterator
{
typedef std::didirectional_iterator_tag iterator_category;
typedef _Tp value_type;
typedef _Tp* pointer;
typedef _Tp& reference;
typedef ptrdiff_t difference_type;
};
但是对于萃取器来说,若是连续空间存储的容器,内部的迭代器和普通类型的指针是相同的,所以萃取器对于传入普通指针也需要相应的转换,但是不同的是迭代器是一种class,而普通指针只是一种普通指针,所以萃取器会使用到偏特化(partial specialization)
template<calss T>
struct iterator_traits
{
typedef typename T::value_type value_type;
typedef typename T::difference_type difference_type
typedef typename T:pointer pointer
typedef typename T::reference reference
typedef typename T::iterator_category iterator_category
};
template<class T>
struct iterator_traits<T*> //native pointer的偏特化
{
typedef T value_type;
typedef std::ptrdiff_t difference_type
typedef T* pointer
typedef T& reference
typedef std::random_access_iterator_tag iterator_category
};
template<class T>
struct iterator_traits<const T*> //const native pointer的偏特化
{
typedef T value_type;
typedef std::ptrdiff_t difference_type
typedef T* pointer
typedef T& reference
typedef std::random_access_iterator_tag iterator_category
};
此处const T *
的value_type不是 const T,而是 T,是因为我们需要value_type声明变量,若是常量变量则无法赋值,所以必须使用非常量变量。
所以不管是迭代器还是普通指针,都可以通过萃取器获得associated types,所以提供给算法的接口就是一致的(这也是范式编程的思想)。