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 ]