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 ]