template<class It>
struct iterator_traits {
typedef typename It::iterator_category iterator_category;
typedef typename It::value_type value_type;
typedef typename It::difference_type difference_type;
typedef typename It::pointer pointer;
typedef typename It::reference reference;
};
template<class T>
struct iterator_traits<T *> {
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef T *pointer;
typedef T& reference;
};
template<class T>
struct iterator_traits<const T *> {
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef const T *pointer;
typedef const T& reference;
};
The template class determines several critical types associated with the iterator type It. It defines the member types iterator_category (a synonym for It::iterator_category), value_type (a synonym for It::value_type), difference_type (a synonym for It::difference_type), pointer (a synonym for It::pointer), and reference (a synonym for It::reference).
The partial specializations determine the critical types associated with an object pointer type T *. In this implementation, you can also use several template functions that do not make use of partial specialization:
template<class C, class T, class Dist>
C _Iter_cat(const iterator<C, T, Dist>&);
template<class T>
random_access_iterator_tag _Iter_cat(const T *);
template<class C, class T, class Dist>
T *_Val_type(const iterator<C, T, Dist>&);
template<class T>
T *_Val_type(const T *);
template<class C, class T, class Dist>
Dist *_Dist_type(const iterator<C, T, Dist>&);
template<class T>
ptrdiff_t *_Dist_type(const T *);
which determine several of the same types a bit more indirectly. You use these functions as arguments on a function call. Their sole purpose is to supply a useful template class parameter to the called function.