In C++20, is the sentinel type of a forward range guaranteed to be the same type as its iterator?

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 std::sentinel_for concept which is a concept that ...

    specifies the relationship between an input_or_output_iterator type and a semiregular type whose values denote a range. The exposition-only concept __WeaklyEqualityComparableWith is described in equality_comparable.

    The 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.