In [iterator.concept.forward], std::forward_iterator
is defined as:
template<class I>
concept forward_iterator =
input_iterator<I> &&
derived_from<ITER_CONCEPT(I), forward_iterator_tag> &&
incrementable<I> &&
sentinel_for<I, I>;
and std::sentinel_for<I, I>
is defined as:
template<class S, class I>
concept sentinel_for =
semiregular<S> &&
input_or_output_iterator<I> &&
weakly-equality-comparable-with<S, I>;
which seems to be redundant in std::forward_iterator
's requirement, since input_iterator
already models input_or_output_iterator
, and incrementable
is defined as:
template<class I>
concept incrementable =
regular<I> &&
weakly_incrementable<I> &&
requires(I i) {
{ i++ } -> same_as<I>;
};
which models regular
which models semiregular
and equality_comparable
which models weakly-equality-comparable-with<I, I>
.
Why does the standard need to add a constraint that seems redundant here, and what are the considerations behind this?