std::forward_iterator
| Defined in header <iterator>
|
||
template< class I > concept forward_iterator = std::input_iterator<I> && std::derived_from</*ITER_CONCEPT*/<I>, std::forward_iterator_tag> && std::incrementable<I> && std::sentinel_for<I, I>; |
(since C++20) | |
This concept refines std::input_iterator by requiring that I also model std::incrementable (thereby making it suitable for multi-pass algorithms), and guaranteeing that two iterators to the same range can be compared against each other.
Iterator concept determination
Definition of this concept is specified via an exposition-only alias template /*ITER_CONCEPT*/.
In order to determine /*ITER_CONCEPT*/<I>, let ITER_TRAITS<I> denote I if the specialization std::iterator_traits<I> is generated from the primary template, or std::iterator_traits<I> otherwise:
- If
ITER_TRAITS<I>::iterator_conceptis valid and names a type,/*ITER_CONCEPT*/<I>denotes the type. - Otherwise, if
ITER_TRAITS<I>::iterator_categoryis valid and names a type,/*ITER_CONCEPT*/<I>denotes the type. - Otherwise, if
std::iterator_traits<I>is generated from the primary template,/*ITER_CONCEPT*/<I>denotes std::random_access_iterator_tag.
(That is,std::derived_from</*ITER_CONCEPT*/<I>, std::forward_iterator_tag>is assumed to betrue.) - Otherwise,
/*ITER_CONCEPT*/<I>does not denote a type and results in a substitution failure.
Semantic requirements
I models std::forward_iterator if, and only if I models all the concepts it subsumes, and given objects i and j of type I:
- Comparison between iterators
iandjhas a defined result if
iandjare iterators to the same underlying sequence, or- both
iandjare value-initialized, in which case they compare equal.
- Pointers and references obtained from a forward iterator into a range remain valid while the range exists.
- If
iandjare dereferenceable, they offer the multi-pass guarantee, that is:
i == jimplies++i == ++j, and((void)[](auto x){ ++x; }(i), *i)is equivalent to*i.
Notes
Unlike the LegacyForwardIterator requirements, the forward_iterator concept does not require dereference to return a reference.
Example
A minimum forward iterator.
#include <cstddef>
#include <iterator>
struct SimpleForwardIterator
{
using difference_type = std::ptrdiff_t;
using value_type = int;
int operator*() const;
SimpleForwardIterator& operator++();
SimpleForwardIterator operator++(int)
{
auto tmp = *this;
++*this;
return tmp;
}
bool operator==(const SimpleForwardIterator&) const;
};
static_assert(std::forward_iterator<SimpleForwardIterator>);
See also
(C++20) |
specifies that a type is an input iterator, that is, its referenced values can be read and it can be both pre- and post-incremented (concept) |
(C++20) |
specifies that a forward_iterator is a bidirectional iterator, supporting movement backwards (concept) |