iterator_traits

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.