C++ named requirements: LegacyForwardIterator
A LegacyForwardIterator is a LegacyIterator that can read data from the pointed-to element.
Unlike LegacyInputIterator and LegacyOutputIterator, it can be used in multipass algorithms.
If a LegacyForwardIterator it
originates from a Container, then it
's value_type
is the same as the container's,
so dereferencing (*it
) obtains the container's value_type
.
Requirements
The type It satisfies LegacyForwardIterator if
- The type It satisfies LegacyInputIterator
- The type It satisfies DefaultConstructible
- Objects of the type It provide multipass guarantee described below
- Let T be the value type of It. The type
std::iterator_traits<It&tg;::reference
must be either- T& or T&& (od C++11) if It satisfies LegacyOutputIterator (It is mutable), or
- const T& or const T&& (od C++11) otherwise (It is constant),
(where T is the type denoted bystd::iterator_traits<It>::value_type
)
- Equality and inequality comparison is defined over all iterators for the same underlying sequence and the value initialized-iterators (od C++14).
And, given
i
, dereferenceable lvalue of type Itreference
, the type denoted bystd::iterator_traits<It>::reference
The following expressions must be valid and have their specified effects
Expression | Return type | Equivalent expression |
---|---|---|
i++ | It | It ip = i; ++i; return ip; |
*i++ | reference |
A mutable LegacyForwardIterator is a LegacyForwardIterator that additionally satisfies the LegacyOutputIterator requirements.
Multipass guarantee
Given a
and b
, dereferenceable iterators of type It
- If
a
andb
compare equal (a == b
is contextually convertible to true) then either they are both non-dereferenceable or*a
and*b
are references bound to the same object. - If
*a
and*b
refer to the same object, thena == b
. - Assignment through a mutable ForwardIterator iterator cannot invalidate the iterator (implicit due to
reference
defined as a true reference). - Incrementing a copy of a does not change the value read from a (formally, either It is a raw pointer type or the expression
(void)++It(a), *a
is equivalent to the expression*a
). a == b
implies++a == ++b
.
Singular iterators (od C++14)
Click to expand
A value-initialized LegacyForwardIterator behaves like the past-the-end iterator of some unspecified empty container: it compares equal to all value-initialized LegacyForwardIterators of the same type.
Concept (od C++20)
Click to expand
For the definition of std::iterator_traits, the following exposition-only concept is defined.
template<class It>
concept __LegacyForwardIterator =
__LegacyInputIterator<It> && std::constructible_from<It> &&
std::is_reference_v<std::iter_reference_t<It>> &&
std::same_as<
std::remove_cvref_t<std::iter_reference_t<It>>,
typename std::indirectly_readable_traits<It>::value_type> &&
requires(It it) {
{ it++ } -> std::convertible_to<const It&>;
{ *it++ } -> std::same_as<std::iter_reference_t<It>>;
};
where the exposition-only concept __LegacyIterator
is described in LegacyIterator#Concept.
Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
LWG 3798 | C++20 | __LegacyForwardIterator requires std::iter_reference_t<It> to be an lvalue reference type | also allows rvalue reference |