std::iterator_traits (3) - Linux Manuals

std::iterator_traits: std::iterator_traits

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 > (until 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 class defines the following types:


* difference_type - a signed integer type that can be used to identify distance between iterators
* value_type - the type of the values that can be obtained by dereferencing the iterator. This type is void for output iterators.
* pointer - defines a pointer to the type iterated over (value_type)
* reference - defines a reference to the type iterated over (value_type)
* iterator_category - the category of the iterator. Must be one of iterator_category_tags.


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 member type iterator_concept to one of iterator_category_tags, to indicate conformance to the iterator concepts. (since C++20)

Template parameters


Iter - the iterator type to retrieve properties for

Member types


Member 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 all five member types difference_type, value_type, pointer, reference, and iterator_category, then this template has no members by any of those names (std::iterator_traits is SFINAE-friendly) (since C++17)
                                                                                                                                                                                                                      (until C++20)
If Iter does not have pointer, but has all other four member types, then the member types are declared as follows:


Member 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 member types are declared as follows:


Member type Definition
difference_type std::incrementable_traits<Iter>::difference_type
value_type std::readable_traits<Iter>::value_type
pointer Iter::pointer if valid, otherwise decltype(std::declval<Iter&>().operator->()) if valid, otherwise void
reference Iter::reference if valid, otherwise std::iter_reference_t<Iter> (since C++20)
                  Iter::iterator_category if valid,
                  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 member types are declared as follows:


Member type Definition
difference_type std::incrementable_traits<Iter>::difference_type if 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 two partial specializations for pointer types T*, which makes it possible to use all iterator-based algorithms with raw pointers.

T* specialization member types


Only specialized if std::is_object_v<T> is true. (since C++20)


Member 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 member types


Member 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

Example


The following example shows a general-purpose reverse() implementation for bidirectional iterators
// Run this code


  #include <iostream>
  #include <iterator>
  #include <vector>
  #include <list>


  template<class BidirIt>
  void my_reverse(BidirIt first, BidirIt last)
  {
      typename std::iterator_traits<BidirIt>::difference_type n = std::distance(first, last);
      --n;
      while(n > 0) {
          typename std::iterator_traits<BidirIt>::value_type tmp = *first;
          *first++ = *--last;
          *last = tmp;
          n -= 2;
      }
  }


  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 (auto n : l) {
          std::cout << n << ' ';
      }
      std::cout << '\n';


      int a[] = {1, 2, 3, 4, 5};
      my_reverse(a, a+5);
      for (int i=0; i<5; ++i) {
          std::cout << a[i] << ' ';
      }
      std::cout << '\n';


  // std::istreambuf_iterator<char> i1(std::cin), i2;
  // my_reverse(i1, i2); // compilation error


  }

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 simple iterators
                           (class template)
(deprecated in C++17)


input_iterator_tag
output_iterator_tag
forward_iterator_tag
bidirectional_iterator_tag
random_access_iterator_tag
contiguous_iterator_tag empty class types used to indicate iterator categories
                           (class)


(C++20)