A forward range
r requires that its iterator is in turn a forward iterator, which in turns requires that the iterator works as its own sentinel. But, does it imply that the actual sentinel type (e.g., the type returned by
r.end()) is of the same type as the iterator itself or doesn't?
No it does not, but it has to be
__WeaklyEqualityComparableWith (an exposition-only
concept) the iterator type returned by
begin() as can be seen in the
concept which is a concept that ...
specifies the relationship between an
input_or_output_iteratortype and a
semiregulartype whose values denote a range. The exposition-only concept
__WeaklyEqualityComparableWithis described in
sentinel_for concept is used by
std::ranges:end() which can be seen in its call signature:
template< class T >
requires /* see link */
constexpr std::sentinel_for<ranges::iterator_t<T>> auto end( T&& t );
This note in
sentinel_for is also of interest:
A sentinel type and its corresponding iterator type are not required to model
equality_comparable_with, because the sentinel type may not be comparable with itself, and they are not required to have a common reference type.