Standard library header <iterator>

From cppreference.com
< cpplrm; | header

This header is part of the iterator library.

Classes

Primitives
provides uniform interface to the properties of an iterator
(class template)
empty class types used to indicate iterator categories
(class)
(deprecated in C++17)
base class to ease the definition of required types for simple iterators
(class template)
Adaptors
iterator adaptor for reverse-order traversal
(class template)
iterator adaptor which dereferences to an rvalue reference
(class template)
iterator adaptor for insertion at the end of a container
(class template)
iterator adaptor for insertion at the front of a container
(class template)
iterator adaptor for insertion into a container
(class template)
Stream Iterators
input iterator that reads from std::basic_istream
(class template)
output iterator that writes to std::basic_ostream
(class template)
input iterator that reads from std::basic_streambuf
(class template)
output iterator that writes to std::basic_streambuf
(class template)

Functions

Adaptors
creates a std::reverse_iterator of type inferred from the argument
(function template)
creates a std::move_iterator of type inferred from the argument
(function template)
creates a std::front_insert_iterator of type inferred from the argument
(function template)
creates a std::back_insert_iterator of type inferred from the argument
(function template)
creates a std::insert_iterator of type inferred from the argument
(function template)
Non-member operators
compares the underlying iterators
(function template)
advances the iterator
(function template)
computes the distance between two iterator adaptors
(function template)
compares the underlying iterators
(function template)
advances the iterator
(function template)
computes the distance between two iterator adaptors
(function template)
compares two istream_iterators
(function template)
compares two istreambuf_iterators
(function template)
Operations
advances an iterator by given distance
(function)
returns the distance between two iterators
(function)
(C++11)
increment an iterator
(function)
(C++11)
decrement an iterator
(function)
Range
(C++11)(C++14)
returns an iterator to the beginning of a container or array
(function)
(C++11)(C++14)
returns an iterator to the end of a container or array
(function)
returns a reverse iterator to a container or array
(function)
(C++14)
returns a reverse end iterator for a container or array
(function)
(C++17)
returns the size of a container or array
(function)
(C++17)
checks whether the container is empty
(function)
(C++17)
obtains the pointer to the underlying array
(function)

Synopsis

namespace std {
    // primitives:
    template<class Iterator> struct iterator_traits;
    template<class T> struct iterator_traits<T*>;
    template<class Category, class T, class Distance = ptrdiff_t,
    class Pointer = T*, class Reference = T&> struct iterator;

    struct input_iterator_tag { };
    struct output_iterator_tag { };
    struct forward_iterator_tag: public input_iterator_tag { };
    struct bidirectional_iterator_tag: public forward_iterator_tag { };
    struct random_access_iterator_tag: public bidirectional_iterator_tag { };

    // iterator operations:
    template <class InputIterator, class Distance>
        constexpr void advance(InputIterator& i, Distance n);
    template <class InputIterator>
        constexpr typename iterator_traits<InputIterator>::difference_type
        distance(InputIterator first, InputIterator last);
    template <class InputIterator>
        constexpr InputIterator next(InputIterator x,
            typename std::iterator_traits<InputIterator>::difference_type n = 1);
    template <class BidirectionalIterator>
        constexpr BidirectionalIterator prev(BidirectionalIterator x,
            typename std::iterator_traits<BidirectionalIterator>::difference_type n = 1);

    // predefined iterators:
    template <class Iterator> class reverse_iterator;
    template <class Iterator1, class Iterator2>
        constexpr bool operator==(
            const reverse_iterator<Iterator1>& x,
            const reverse_iterator<Iterator2>& y);
    template <class Iterator1, class Iterator2>
        constexpr bool operator<(
            const reverse_iterator<Iterator1>& x,
            const reverse_iterator<Iterator2>& y);
    template <class Iterator1, class Iterator2>
        constexpr bool operator!=(
            const reverse_iterator<Iterator1>& x,
            const reverse_iterator<Iterator2>& y);
    template <class Iterator1, class Iterator2>
        constexpr bool operator>(
            const reverse_iterator<Iterator1>& x,
            const reverse_iterator<Iterator2>& y);
    template <class Iterator1, class Iterator2>
        constexpr bool operator>=(
            const reverse_iterator<Iterator1>& x,
            const reverse_iterator<Iterator2>& y);
    template <class Iterator1, class Iterator2>
        constexpr bool operator<=(
            const reverse_iterator<Iterator1>& x,
            const reverse_iterator<Iterator2>& y);

    template <class Iterator1, class Iterator2>
        constexpr auto operator-(
            const reverse_iterator<Iterator1>& x,
            const reverse_iterator<Iterator2>& y) ->decltype(y.base() - x.base());
    template <class Iterator>
        constexpr reverse_iterator<Iterator>
        operator+(
            typename reverse_iterator<Iterator>::difference_type n,
            const reverse_iterator<Iterator>& x);
    template <class Iterator>
        constexpr reverse_iterator<Iterator> make_reverse_iterator(Iterator i);

    template <class Container> class back_insert_iterator;
    template <class Container>
        back_insert_iterator<Container> back_inserter(Container& x);

    template <class Container> class front_insert_iterator;
    template <class Container>
        front_insert_iterator<Container> front_inserter(Container& x);

    template <class Container> class insert_iterator;
    template <class Container>
        insert_iterator<Container> inserter(Container& x, typename Container::iterator i);

    template <class Iterator> class move_iterator;
    template <class Iterator1, class Iterator2>
        constexpr bool operator==(
            const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
    template <class Iterator1, class Iterator2>
        constexpr bool operator!=(
            const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
    template <class Iterator1, class Iterator2>
        constexpr bool operator<(
            const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
    template <class Iterator1, class Iterator2>
        constexpr bool operator<=(
            const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
    template <class Iterator1, class Iterator2>
        constexpr bool operator>(
            const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);
    template <class Iterator1, class Iterator2>
        constexpr bool operator>=(
            const move_iterator<Iterator1>& x, const move_iterator<Iterator2>& y);

    template <class Iterator1, class Iterator2>
        constexpr auto operator-(
            const move_iterator<Iterator1>& x,
            const move_iterator<Iterator2>& y) -> decltype(x.base() - y.base());
    template <class Iterator>
        constexpr move_iterator<Iterator> operator+(
            typename move_iterator<Iterator>::difference_type n, 
            const move_iterator<Iterator>& x);
    template <class Iterator>
        constexpr move_iterator<Iterator> make_move_iterator(Iterator i);

    // stream iterators:
    template <class T, class CharT = char, class traits = char_traits<CharT>,
            class Distance = ptrdiff_t>
        class istream_iterator;
    template <class T, class CharT, class traits, class Distance>
        bool operator==(const istream_iterator<T,CharT,traits,Distance>& x,
            const istream_iterator<T,CharT,traits,Distance>& y);
    template <class T, class CharT, class traits, class Distance>
        bool operator!=(const istream_iterator<T,CharT,traits,Distance>& x,
            const istream_iterator<T,CharT,traits,Distance>& y);

    template <class T, class CharT = char, class traits = char_traits<CharT> >
        class ostream_iterator;

    template<class CharT, class traits = char_traits<CharT> >
        class istreambuf_iterator;
    template <class CharT, class traits>
        bool operator==(const istreambuf_iterator<CharT,traits>& a,
            const istreambuf_iterator<CharT,traits>& b);
    template <class CharT, class traits>
        bool operator!=(const istreambuf_iterator<CharT,traits>& a,
            const istreambuf_iterator<CharT,traits>& b);

    template <class CharT, class traits = char_traits<CharT> >
        class ostreambuf_iterator;

    // range access:
    template<class C> constexpr auto begin(C& c) -> decltype(c.begin());
    template<class C> constexpr auto begin(const C& c) -> decltype(c.begin());
    template<class C> constexpr auto end(C& c) -> decltype(c.end());
    template<class C> constexpr auto end(const C& c) -> decltype(c.end());
    template<class T, size_t N> constexpr T* begin(T (&array)[N]) noexcept;
    template<class T, size_t N> constexpr T* end(T (&array)[N]) noexcept;
    template<class C> constexpr auto cbegin(const C& c) noexcept(noexcept(std::begin(c)))
        -> decltype(std::begin(c));
    template<class C> constexpr auto cend(const C& c) noexcept(noexcept(std::end(c)))
        -> decltype(std::end(c));
    template<class C> constexpr auto rbegin(C& c) -> decltype(c.rbegin());
    template<class C> constexpr auto rbegin(const C& c) -> decltype(c.rbegin());
    template<class C> constexpr auto rend(C& c) -> decltype(c.rend());
    template<class C> constexpr auto rend(const C& c) -> decltype(c.rend());
    template<class T, size_t N> constexpr reverse_iterator<T*> rbegin(T (&array)[N]);
    template<class T, size_t N> constexpr reverse_iterator<T*> rend(T (&array)[N]);
    template<class E> constexpr reverse_iterator<const E*> rbegin(initializer_list<E> il);
    template<class E> constexpr reverse_iterator<const E*> rend(initializer_list<E> il);
    template<class C> constexpr auto crbegin(const C& c) -> decltype(std::rbegin(c));
    template<class C> constexpr auto crend(const C& c) -> decltype(std::rend(c));

    // container access:
    template<class C> constexpr auto size(const C& c) -> decltype(c.size());
    template<class T, size_t N> constexpr size_t size(const T (&array)[N]) noexcept;
    template<class C> [[nodiscard]]
        constexpr auto empty(const C& c) -> decltype(c.empty());
    template<class T, size_t N> [[nodiscard]]
        constexpr bool empty(const T (&array)[N]) noexcept;
    template<class E> [[nodiscard]]
        constexpr bool empty(initializer_list<E> il) noexcept;
    template<class C> constexpr auto data(C& c) -> decltype(c.data());
    template<class C> constexpr auto data(const C& c) -> decltype(c.data());
    template<class T, size_t N> constexpr T* data(T (&array)[N]) noexcept;
    template<class E> constexpr const E* data(initializer_list<E> il) noexcept;
}

Class std::iterator_traits

template<class Iterator> struct iterator_traits {
    using difference_type   = typename Iterator::difference_type;
    using value_typet       = typename Iterator::value_type;
    using pointer           = typename Iterator::pointer;
    using reference         = typename Iterator::reference;
    using iterator_category = typename Iterator::iterator_category;
};

template<class T> struct iterator_traits<T*> {
    using difference_type   = ptrdiff_t;
    using value_type        = remove_cv_t<T>;
    using pointer           = T*;
    using reference         = T&;
    using iterator_category = random_access_iterator_tag;
};

Iterator tags

struct input_iterator_tag { };
struct output_iterator_tag { };
struct forward_iterator_tag: public input_iterator_tag { };
struct bidirectional_iterator_tag: public forward_iterator_tag { };
struct random_access_iterator_tag: public bidirectional_iterator_tag { };

Class std::reverse_iterator

template <class Iterator>
class reverse_iterator {
public:
    using iterator_type     = Iterator;
    using iterator_category = typename iterator_traits<Iterator>::iterator_category;
    using value_type        = typename iterator_traits<Iterator>::value_type;
    using difference_type   = typename iterator_traits<Iterator>::difference_type;
    using pointer           = typename iterator_traits<Iterator>::pointer;
    using reference         = typename iterator_traits<Iterator>::reference;

    constexpr reverse_iterator();
    constexpr explicit reverse_iterator(Iterator x);
    template <class U> constexpr reverse_iterator(const reverse_iterator<U>& u);
    template <class U> constexpr reverse_iterator& operator=(const reverse_iterator<U>& u);

    constexpr Iterator base() const; // explicit
    constexpr reference operator*() const;
    constexpr pointer   operator->() const;

    constexpr reverse_iterator& operator++();
    constexpr reverse_iterator  operator++(int);
    constexpr reverse_iterator& operator--();
    constexpr reverse_iterator  operator--(int);

    constexpr reverse_iterator  operator+ (difference_type n) const;
    constexpr reverse_iterator& operator+=(difference_type n);
    constexpr reverse_iterator  operator- (difference_type n) const;
    constexpr reverse_iterator& operator-=(difference_type n);

    constexpr /*unspecified*/ operator[](difference_type n) const;
protected:
    Iterator current;
};

Class std::back_insert_iterator

template<class Container>
class back_insert_iterator {
protected:
    Container* container;

public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = void;
    using pointer           = void;
    using reference         = void;
    using container_type    = Container;

    explicit back_insert_iterator(Container& x);
    back_insert_iterator& operator=(const typename Container::value_type& value);
    back_insert_iterator& operator=(typename Container::value_type&& value);

    back_insert_iterator& operator*();
    back_insert_iterator& operator++();
    back_insert_iterator operator++(int);
};

Class std::front_insert_iterator

template<class Container>
class front_insert_iterator {
protected:
    Container* container;

public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = void;
    using pointer           = void;
    using reference         = void;
    using container_type    = Container;

    explicit front_insert_iterator(Container& x);
    front_insert_iterator& operator=(const typename Container::value_type& value);
    front_insert_iterator& operator=(typename Container::value_type&& value);

    front_insert_iterator& operator*();
    front_insert_iterator& operator++();
    front_insert_iterator operator++(int);
};

Class std::insert_iterator

template<class Container>
class insert_iterator {
protected:
    Container* container;
    typename Container::iterator iter;

public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = void;
    using pointer           = void;
    using reference         = void;
    using container_type    = Container;

    insert_iterator(Container& x, typename Container::iterator i);
    insert_iterator& operator=(const typename Container::value_type& value);
    insert_iterator& operator=(typename Container::value_type&& value);

    insert_iterator& operator*();
    insert_iterator& operator++();
    insert_iterator& operator++(int);
};

Class std::move_iterator

template<class Iterator>
class move_iterator {
public:
    using iterator_type     = Iterator;
    using iterator_category = typename iterator_traits<Iterator>::iterator_category;
    using value_type        = typename iterator_traits<Iterator>::value_type;
    using difference_type   = typename iterator_traits<Iterator>::difference_type;
    using pointer           = Iterator;
    using reference         = /*see below*/ ;

    constexpr move_iterator();
    constexpr explicit move_iterator(Iterator i);
    template<class U> constexpr move_iterator(const move_iterator<U>& u);
    template<class U> constexpr move_iterator& operator=(const move_iterator<U>& u);

    constexpr iterator_type base() const;
    constexpr reference operator*() const;
    constexpr pointer operator->() const;

    constexpr move_iterator& operator++();
    constexpr move_iterator operator++(int);
    constexpr move_iterator& operator--();
    constexpr move_iterator operator--(int);

    constexpr move_iterator operator+(difference_type n) const;
    constexpr move_iterator& operator+=(difference_type n);
    constexpr move_iterator operator-(difference_type n) const;
    constexpr move_iterator& operator-=(difference_type n);
    constexpr /*unspecified*/ operator[](difference_type n) const;

private:
    Iterator current; // exposition only
};

Class std::istream_iterator

template<class T, class CharT = char, class Traits = char_traits<CharT>,
         class Distance = ptrdiff_t>
class istream_iterator {
public:
    using iterator_category = input_iterator_tag;
    using value_type        = T;
    using difference_type   = Distance;
    using pointer           = const T*;
    using reference         = const T&;
    using char_type         = CharT;
    using traits_type       = Traits;
    using istream_type      = basic_istream<CharT, Traits>;

    constexpr istream_iterator();
    istream_iterator(istream_type& s);
    istream_iterator(const istream_iterator& x) = default;
    ~istream_iterator() = default;

    const T& operator*() const;
    const T* operator->() const;
    istream_iterator& operator++();
    istream_iterator operator++(int);

private:
    basic_istream<CharT, Traits>* in_stream; // exposition only
    T value;                                 // exposition only
};

Class std::ostream_iterator

template<class T, class CharT = char, class Traits = char_traits<CharT>>
class ostream_iterator {
public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = void;
    using pointer           = void;
    using reference         = void;
    using char_type         = CharT;
    using traits_type       = Traits;
    using ostream_type      = basic_ostream<CharT, Traits>;

    ostream_iterator(ostream_type& s);
    ostream_iterator(ostream_type& s, const CharT* delimiter);
    ostream_iterator(const ostream_iterator& x);
    ~ostream_iterator();

    ostream_iterator& operator=(const T& value);
    ostream_iterator& operator*();
    ostream_iterator& operator++();
    ostream_iterator& operator++(int);

private:
    basic_ostream<CharT, Traits>* out_stream; // exposition only
    const CharT* delim;                       // exposition only
};

Class std::istreambuf_iterator

template<class CharT, class Traits = char_traits<CharT>>
class istreambuf_iterator {
public:
    using iterator_category = input_iterator_tag;
    using value_type        = CharT;
    using difference_type   = typename Traits::off_type;
    using pointer           = /*unspecified*/;
    using reference         = CharT;
    using char_type         = CharT;
    using traits_type       = Traits;
    using int_type          = typename Traits::int_type;
    using streambuf_type    = basic_streambuf<CharT, Traits>;
    using istream_type      = basic_istream<CharT, Traits>;

    class proxy; // exposition only

    constexpr istreambuf_iterator() noexcept;
    istreambuf_iterator(const istreambuf_iterator&) noexcept = default;
    ~istreambuf_iterator() = default;

    istreambuf_iterator(istream_type& s) noexcept;
    istreambuf_iterator(streambuf_type* s) noexcept;
    istreambuf_iterator(const proxy& p) noexcept;
    CharT operator*() const;
    istreambuf_iterator& operator++();
    proxy operator++(int);
    bool equal(const istreambuf_iterator& b) const;

private:
    streambuf_type* sbuf_; // exposition only
};

template<class CharT, class Traits = char_traits<CharT>>
class istreambuf_iterator<CharT, Traits>::proxy { // exposition only
    CharT keep_;
    basic_streambuf<CharT, Traits>* sbuf_;
    proxy(CharT c, basic_streambuf<CharT, Traits>* sbuf)
        : keep_(c), sbuf_(sbuf) { }
public:
    CharT operator*() { return keep_; }
};

Class std::ostreambuf_iterator

template<class CharT, class Traits = char_traits<CharT>>
class ostreambuf_iterator {
public:
    using iterator_category = output_iterator_tag;
    using value_type        = void;
    using difference_type   = void;
    using pointer           = void;
    using reference         = void;
    using char_type         = CharT;
    using traits_type       = Traits;
    using streambuf_type    = basic_streambuf<CharT, Traits>;
    using ostream_type      = basic_ostream<CharT, Traits>;

    ostreambuf_iterator(ostream_type& s) noexcept;
    ostreambuf_iterator(streambuf_type* s) noexcept;
    ostreambuf_iterator& operator=(CharT c);

    ostreambuf_iterator& operator*();
    ostreambuf_iterator& operator++();
    ostreambuf_iterator& operator++(int);
    bool failed() const noexcept;

private:
    streambuf_type* sbuf_; // exposition only
};

Class std::iterator

template<class Category, class T, class Distance = ptrdiff_t,
         class Pointer = T*, class Reference = T&>
struct iterator {
    typedef T           value_type;
    typedef Distance    difference_type;
    typedef Pointer     pointer;
    typedef Reference   reference;
    typedef Category    iterator_category;
};