std::reverse_iterator
| Defined in header <iterator>
|
||
template< class Iter > class reverse_iterator; |
||
std::reverse_iterator is an iterator adaptor that reverses the direction of a given iterator, which must be at least a LegacyBidirectionalIterator or model bidirectional_iterator(since C++20). In other words, when provided with a bidirectional iterator, std::reverse_iterator produces a new iterator that moves from the end to the beginning of the sequence defined by the underlying bidirectional iterator.
For a reverse iterator r constructed from an iterator i, the relationship &*r == &*(i - 1) is always true (as long as r is dereferenceable); thus a reverse iterator constructed from a one-past-the-end iterator dereferences to the last element in a sequence.
This is the iterator returned by member functions rbegin() and rend() of the standard library containers.
Nested types
|
(until C++20) | ||||||||||||||||
|
(since C++20) |
Data members
| Member | Description |
Iter current
|
the underlying iterator (protected member object) |
Member functions
constructs a new reverse_iterator (public member function) | |
assigns another reverse_iterator (public member function) | |
| accesses the underlying iterator (public member function) | |
| accesses the pointed-to element (public member function) | |
| accesses an element by index (public member function) | |
advances or decrements the reverse_iterator (public member function) |
Non-member functions
| compares the underlying iterators (function template) | |
| advances the iterator (function template) | |
| computes the distance between two iterator adaptors (function template) | |
(C++20) |
casts the result of dereferencing the adjusted underlying iterator to its associated rvalue reference type (function) |
(C++20) |
swaps the objects pointed to by two adjusted underlying iterators (function template) |
(C++14) |
creates a std::reverse_iterator of type inferred from the argument (function template) |
Helper templates
template< class Iterator1, class Iterator2 > requires (!std::sized_sentinel_for<Iterator1, Iterator2>) inline constexpr bool disable_sized_sentinel_for <std::reverse_iterator<Iterator1>, std::reverse_iterator<Iterator2>> = true; |
(since C++20) | |
This partial specialization of std::disable_sized_sentinel_for prevents specializations of reverse_iterator from satisfying sized_sentinel_for if their underlying iterators do not satisfy the concept.
Possible implementation
Below is a partial implementation focusing on the way the inner iterator is stored, calling std::prev only when the content is fetched via operator*.
template<class It>
class reverse_iterator
{
protected:
It current = It();
public:
reverse_iterator() = default;
constexpr explicit reverse_iterator(It itr) : current(itr) {}
template<class U>
requires (!std::is_same_v<U, It> && std::convertible_to<const U&, It>)
constexpr explicit reverse_iterator(const U& other) : current(other.base()) {}
constexpr decltype(auto) operator*() const
{
return *std::prev(current); // <== returns the content of prev
}
constexpr reverse_iterator& operator++() { --current; return *this; }
constexpr reverse_iterator operator++(int) { auto tmp = *this; ++(*this); return tmp; }
constexpr reverse_iterator& operator--() { ++current; return *this; }
constexpr reverse_iterator operator--(int) { auto tmp = *this; --(*this); return tmp; }
constexpr It base() const { return current; }
// Other member functions, friend functions, and member typedefs are not shown here.
};
|
Notes
std::reverse_iterator does not work with iterators whose dereference returns a reference to a member of *this (so-called “stashing iterators”). An example of a stashing iterator is MSVC STL's std::filesystem::path::iterator.
Example
#include <cstddef>
#include <iostream>
#include <iterator>
template<typename T, std::size_t SIZE>
class Stack
{
T arr[SIZE];
std::size_t pos = 0;
public:
T pop()
{
return arr[--pos];
}
Stack& push(const T& t)
{
arr[pos++] = t;
return *this;
}
// we wish that looping on Stack would be in LIFO order
// thus we use std::reverse_iterator as an adaptor to existing iterators
// (which are in this case the simple pointers: [arr, arr + pos)
auto begin() { return std::reverse_iterator(arr + pos); }
auto end() { return std::reverse_iterator(arr); }
};
int main()
{
Stack<int, 8> s;
s.push(5).push(15).push(25).push(35);
for (int val : s)
std::cout << val << ' ';
std::cout << '\n';
}
Output:
35 25 15 5
See also
(C++14) |
creates a std::reverse_iterator of type inferred from the argument (function template) |
(deprecated in C++17) |
base class to ease the definition of required types for simple iterators (class template) |