std::iterator_traits(3)

NAME
std::iterator_traits - std::iterator_traits

Synopsis
   Defined in header <iterator>
   template< class Iter >
   struct iterator_traits;
   template< class T >
   struct iterator_traits<T*>;
   template< class T > (removed in C++20)
   struct iterator_traits<const T*>;
   std::iterator_traits is the type trait class that provides uniform interface to the
   properties of LegacyIterator types. This makes it possible to implement algorithms
   only in terms of iterators.
   The template can be specialized for user-defined iterators so that the information
   about the iterator can be retrieved even if the type does not provide the usual
   typedefs.
   User specializations may define the nested type iterator_concept to
   one of iterator category tags, to indicate conformance to the iterator (since C++20)
   concepts.

Template parameters
   Iter - the iterator type to retrieve properties for
   Nested types
   Nested type Definition
   difference_type Iter::difference_type
   value_type Iter::value_type
   pointer Iter::pointer
   reference Iter::reference
   iterator_category Iter::iterator_category
   If Iter does not have any of the five nested types above, then this template (since
   has no members by any of those names (std::iterator_traits is C++17)
   SFINAE-friendly). (until
                        C++20)
   If Iter does not have pointer, but has all four remaining nested types, then
   these four nested types are declared as follows:
   Nested type Definition
   difference_type Iter::difference_type
   value_type Iter::value_type
   pointer void
   reference Iter::reference
   iterator_category Iter::iterator_category
   Otherwise, if Iter satisfies the exposition-only concept
   __LegacyInputIterator, the nested types are declared as follows:
   Nested type Definition
   difference_type std::incrementable_traits<Iter>::difference_type
   value_type std::indirectly_readable_traits<Iter>::value_type
                       * Iter::pointer if valid.
   pointer * Otherwise decltype(std::declval<Iter&>().operator->())
                        if valid.
                       * Otherwise void.
   reference * Iter::reference if valid.
                       * Otherwise std::iter_reference_t<Iter>. (since
                       * Iter::iterator_category if valid. C++20)
                       * Otherwise, std::random_access_iterator_tag if Iter
                        satisfies __LegacyRandomAccessIterator.
   iterator_category * Otherwise, std::bidirectional_iterator_tag if Iter
                        satisfies __LegacyBidirectionalIterator.
                       * Otherwise, std::forward_iterator_tag if Iter satisfies
                        __LegacyForwardIterator.
                       * Otherwise, std::input_iterator_tag.
   Otherwise, if Iter satisfies the exposition-only concept __LegacyIterator,
   the nested types are declared as follows:
   Nested type Definition
                       * std::incrementable_traits<Iter>::difference_type if
   difference_type valid.
                       * Otherwise void.
   value_type void
   pointer void
   reference void
   iterator_category std::output_iterator_tag
   Otherwise, this template has no members by any of those names
   (std::iterator_traits is SFINAE-friendly).

Specializations
   This type trait may be specialized for user-provided types that may be used as
   iterators. The standard library provides partial specializations for pointer types
   T*, which makes it possible to use all iterator-based algorithms with raw pointers.
   The standard library also provides partial specializations for some (since C++20)
   standard iterator adaptors.
     T* specialization nested types
   Only specialized if std::is_object_v<T> is true. (since C++20)
   Nested type Definition
   difference_type std::ptrdiff_t
                        T
   value_type (until C++20)
                        std::remove_cv_t<T>
                        (since C++20)
   pointer T*
   reference T&
   iterator_category std::random_access_iterator_tag
   iterator_concept (since C++20) std::contiguous_iterator_tag
       const T* specialization nested types
   Nested type Definition
   difference_type std::ptrdiff_t (until C++20)
   value_type T
   pointer const T*
   reference const T&
   iterator_category std::random_access_iterator_tag
     Specializations for library types
                        provides uniform interface to the
   std::iterator_traits<std::common_iterator> properties of the std::common_iterator
   (C++20) type
                        (class template specialization)
                        provides uniform interface to the
   std::iterator_traits<std::counted_iterator> properties of the std::counted_iterator
   (C++20) type
                        (class template specialization)

Example
   Shows a general-purpose std::reverse() implementation for bidirectional iterators. // Run this code
 #include <iostream>
 #include <iterator>
 #include <list>
 #include <vector>
 template<class BidirIt>
 void my_reverse(BidirIt first, BidirIt last)
 {
     typename std::iterator_traits<BidirIt>::difference_type n = std::distance(first, last);
     for (--n; n > 0; n -= 2)
     {
         typename std::iterator_traits<BidirIt>::value_type tmp = *first;
         *first++ = *--last;
         *last = tmp;
     }
 }
 int main()
 {
     std::vector<int> v{1, 2, 3, 4, 5};
     my_reverse(v.begin(), v.end());
     for (int n : v)
         std::cout << n << ' ';
     std::cout << '\n';
     std::list<int> l{1, 2, 3, 4, 5};
     my_reverse(l.begin(), l.end());
     for (int n : l)
         std::cout << n << ' ';
     std::cout << '\n';
     int a[]{1, 2, 3, 4, 5};
     my_reverse(a, a + std::size(a));
     for (int n : a)
         std::cout << n << ' ';
     std::cout << '\n';
 // std::istreambuf_iterator<char> i1(std::cin), i2;
 // my_reverse(i1, i2); // compilation error: i1, i2 are input iterators
 }

Output:
 5 4 3 2 1
 5 4 3 2 1
 5 4 3 2 1

See also
   iterator base class to ease the definition of required types for
   (deprecated in C++17) simple iterators
                        (class template)
   input_iterator_tag
   output_iterator_tag
   forward_iterator_tag empty class types used to indicate iterator categories
   bidirectional_iterator_tag (class)
   random_access_iterator_tag
   contiguous_iterator_tag
   (C++20)
   iter_value_t
   iter_reference_t
   iter_const_reference_t
   iter_difference_t
   iter_rvalue_reference_t
   iter_common_reference_t computes the associated types of an iterator
   (C++20) (alias template)
   (C++20)
   (C++23)
   (C++20)
   (C++20)
   (C++20)