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

### 3602. `reverse_iterator`'s converting assignment is overconstrained

Section: 23.5.1.4 [reverse.iter.cons], 23.5.3.4 [move.iter.cons] Status: New Submitter: Hewill Kang Opened: 2021-09-26 Last modified: 2021-10-14

Priority: 3

View all other issues in [reverse.iter.cons].

View all issues with New status.

Discussion:

In order to remove the incorrect bi-convertibility of `reverse_iterator<int*>` and `reverse_iterator<const int*>`, LWG 3435 adds two constraints to `reverse_iterator`'s converting assignment, namely `convertible_to<const U&, Iterator>` and `assignable_from<Iterator&, const U&>`, but since this function only assigns `u.current` to `current`, there is no need to require `convertible_to<const U&, Iterator>` — the latter is sufficient.

We should remove this constraint and be consistent with the `move_sentinel` and `counted_iterator`' converting assignment.

[2021-10-14; Reflector poll]

Set priority to 3 after reflector poll.

[Tim Song commented:]

This was intentional, but I think we missed the fact that `counted_iterator` did something else already. These should probably be made consistent one way or another.

[Tomasz Kamiński commented]

The `move_iterator`/`reverse_iterator` were present before C++20, and this change restores their compatibility with C++17 code, where only assignment was required. They are materially different from adapters introduced with C++20, and I believe we should put more weight into backward compatibility than consistency with newer iterator wrappers.

Proposed resolution:

This wording is relative to N4892.

1. Modify 23.5.1.4 [reverse.iter.cons] as indicated:

   >     template<class U>
   >       constexpr reverse_iterator&
   >         operator=(const reverse_iterator<U>& u);

   > > -5- Constraints: `is_same_v<U, Iterator>` is `false`, `const U&` models `convertible_to<Iterator>`, and `assignable_from<Iterator&, const U&>` is modeled.

   > > -6- Effects: Assigns `u.current` to `current`.

   > > -7- Returns: `*this`.

2. Modify 23.5.3.4 [move.iter.cons] as indicated:

   > [Drafting note: As drive-by fix a missing "Returns: `*this`" has been added as well.]

   >     template<class U> constexpr move_iterator& operator=(const move_iterator<U>& u);

   > > -5- Constraints: `is_same_v<U, Iterator>` is `false`, `const U&` models `convertible_to<Iterator>`, and `assignable_from<Iterator&, const U&>` is modeled.

   > > -6- Effects: Assigns `u.current` to `current`.

   > > -?- Returns: `*this`.