9 Iterators library [iterators]

9.6 Iterator primitives [iterator.primitives]

9.6.1 Iterator traits [iterator.traits]

For the sake of backwards compatibility, this document specifies the existence of an iterator_traits alias that collects an iterator's associated types. It is defined as if:

  template <InputIterator I> struct __pointer_type {        // exposition only
    using type = add_pointer_t<reference_t<I>>;
  };
  template <InputIterator I>
    requires requires(I i) { { i.operator->() } -> auto&&; }
  struct __pointer_type<I> {                                    // exposition only
    using type = decltype(declval<I>().operator->());
  };
  template <class> struct __iterator_traits { };                // exposition only
  template <Iterator I> struct __iterator_traits<I> {
    using difference_type = difference_type_t<I>;
    using value_type = void;
    using reference = void;
    using pointer = void;
    using iterator_category = output_iterator_tag;
  };
  template <InputIterator I> struct __iterator_traits<I> {  // exposition only
    using difference_type = difference_type_t<I>;
    using value_type = value_type_t<I>;
    using reference = reference_t<I>;
    using pointer = typename __pointer_type<I>::type;
    using iterator_category = iterator_category_t<I>;
  };
  template <class I>
    using iterator_traits = __iterator_traits<I>;

Note: iterator_traits is an alias template to prevent user code from specializing it.  — end note ]

Example: To implement a generic reverse function, a C++ program can do the following:

template <BidirectionalIterator I>
void reverse(I first, I last) {
  difference_type_t<I> n = distance(first, last);
  --n;
  while(n > 0) {
    value_type_t<I> tmp = *first;
    *first++ = *--last;
    *last = tmp;
    n -= 2;
  }
}

 — end example ]