Iterator concepts | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Iterator primitives | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Algorithm concepts and utilities | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Indirect callable concepts | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Common algorithm requirements | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Utilities | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Iterator adaptors | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
Member functions | ||||
Non-member functions | ||||
(C++20) | ||||
(C++20) | ||||
(C++14) |
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 aLegacyBidirectionalIterator or modelbidirectional_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 iteratorr constructed from an iteratori, the relationship&*r==&*(i-1) is alwaystrue (as long asr isdereferenceable); 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 functionsrbegin()
andrend()
of thestandard library containers.
Contents |
| (until C++20) | ||||||||||||||||
| (since C++20) |
Member | Description |
Iter current | the underlying iterator (protected member object) |
constructs a newreverse_iterator (public member function)[edit] | |
assigns anotherreverse_iterator (public member function)[edit] | |
accesses the underlying iterator (public member function)[edit] | |
accesses the pointed-to element (public member function)[edit] | |
accesses an element by index (public member function)[edit] | |
advances or decrements thereverse_iterator (public member function)[edit] |
compares the underlying iterators (function template)[edit] | |
advances the iterator (function template)[edit] | |
computes the distance between two iterator adaptors (function template)[edit] | |
(C++20) | casts the result of dereferencing the adjusted underlying iterator to its associated rvalue reference type (function)[edit] |
(C++20) | swaps the objects pointed to by two adjusted underlying iterators (function template)[edit] |
(C++14) | creates astd::reverse_iterator of type inferred from the argument (function template)[edit] |
template<class Iterator1,class Iterator2> requires(!std::sized_sentinel_for<Iterator1, Iterator2>) | (since C++20) | |
This partial specialization ofstd::disable_sized_sentinel_for
prevents specializations ofreverse_iterator
from satisfyingsized_sentinel_for
if their underlying iterators do not satisfy the concept.
Below is a partial implementation focusing on the way the inner iterator is stored, callingstd::prev only when the content is fetched viaoperator*.
template<class It>class reverse_iterator{protected: It current= It();public: reverse_iterator()=default;constexprexplicit reverse_iterator(It itr): current(itr){}template<class U> requires(!std::is_same_v<U, It>&&std::convertible_to<const U&, It>)constexprexplicit 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.}; |
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 isMSVC STL'sstd::filesystem::path::iterator.
#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
(C++14) | creates astd::reverse_iterator of type inferred from the argument (function template)[edit] |
(deprecated in C++17) | base class to ease the definition of required types for simple iterators (class template)[edit] |