Issue 3736: move_iterator missing disable_sized_sentinel_for specialization (original) (raw)


This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++23 status.

3736. move_iterator missing disable_sized_sentinel_for specialization

Section: 24.2 [iterator.synopsis] Status: C++23 Submitter: Hewill Kang Opened: 2022-07-14 Last modified: 2023-11-22

Priority: Not Prioritized

View all other issues in [iterator.synopsis].

View all issues with C++23 status.

Discussion:

Since reverse_iterator::operator- is not constrained, the standard adds a disable_sized_sentinel_for specialization for it to avoid situations where the underlying iterator can be subtracted making reverse_iterator accidentally model sized_sentinel_for.

However, given that move_iterator::operator- is also unconstrained and the standard does not have the disable_sized_sentinel_for specialization for it, this makes subrange<move_iterator<I>, move_iterator<I>> unexpectedly satisfy sized_range and incorrectly use I::operator- to get size when Ican be subtracted but not modeled sized_sentinel_for<I>.

In addition, since P2520 makes move_iterator no longer just input_iterator, ranges::size can get the size of the range by subtracting two move_iterator pairs, this also makes r | views::as_rvalue may satisfy sized_range when neither r nor r | views::reverse is sized_range.

We should add a move_iterator version of the disable_sized_sentinel_forspecialization to the standard to avoid the above situation.

[2022-08-23; Reflector poll]

Set status to Tentatively Ready after six votes in favour during reflector poll.

"but I don't think the issue text is quite right - bothmove_iterator and reverse_iterator'soperator- are constrained on x.base() - y.base()being valid."

Does anyone remember why we did this for reverse_iteratorand not move_iterator?

[2022-11-12 Approved at November 2022 meeting in Kona. Status changed: Voting → WP.]

Proposed resolution:

This wording is relative to N4910.

  1. Modify 24.2 [iterator.synopsis], header <iterator> synopsis, as indicated:

    namespace std::ranges {
    […]
    template
    constexpr move_iterator make_move_iterator(Iterator i);

    template<class Iterator1, class Iterator2>
    requires (!sized_sentinel_for<Iterator1, Iterator2>)

inline constexpr bool disable_sized_sentinel_for<move_iterator,
move_iterator> = true;

[…]
}