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

### 3736. `move_iterator` missing `disable_sized_sentinel_for` specialization

Section: 25.2 [iterator.synopsis] Status: WP Submitter: Hewill Kang Opened: 2022-07-14 Last modified: 2022-11-17

Priority: Not Prioritized

View all other issues in [iterator.synopsis].

View all issues with WP 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 `I` can 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_for` specialization 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 - both `move_iterator` and `reverse_iterator`'s `operator-` are constrained on `x.base() - y.base()` being valid."

Does anyone remember why we did this for `reverse_iterator` and 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 25.2 [iterator.synopsis], header `<iterator>` synopsis, as indicated:

   >     namespace std::ranges {
   >       […]
   >       template<class Iterator>
   >         constexpr move_iterator<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<Iterator1>,
   >                                                          move_iterator<Iterator2>> = true;

   >       […]
   >     }