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.

### 3265. `move_iterator`'s conversions are more broken after P1207

Section: 23.5.3.4 [move.iter.cons] Status: WP Submitter: Casey Carter Opened: 2019-08-23 Last modified: 2020-11-09

Priority: 2

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

View all issues with WP status.

Discussion:

The converting constructor and assignment operator specified in 23.5.3.4 [move.iter.cons] were technically broken before P1207:

- 23.5.3.4 [move.iter.cons] para 3 (and 5 for that matter) is an instance of LWG 3105; it should instead mandate that `u.base()` is convertible to `Iterator`.

- 23.5.3.4 [move.iter.cons] para 5 uses "is convertible" to guard an assignment operation instead of a conversion; it should instead mandate.

After applying P1207R4 "Movability of Single-pass Iterators", `u.base()` is not always well-formed, exacerbating the problem. These operations must ensure that `u.base()` is well-formed.

Drive-by:

- Let's burninate "Constructs a `move_iterator`" while we're touching this subclause.

- We'll also burninate "Iterator operations applied..." since the requirement it wants to impose is covered (and indeed must be covered) by the specifications of those other operations.

[2019-09-14 Priority set to 2 based on reflector discussion]

Previous resolution [SUPERSEDED]:

> This wording is relative to N4830.

> 1. Modify 23.5.3.4 [move.iter.cons] as indicated:

>    >     constexpr move_iterator();

>    > > -1- Effects: Constructs a `move_iterator`, v Value-initializes ing `current`. Iterator operations applied to the resulting iterator have defined behavior if and only if the corresponding operations are defined on a value-initialized iterator of type `Iterator`.

>    >     constexpr explicit move_iterator(Iterator i);

>    > > -2- Effects: Constructs a move_iterator, i Initializes ing `current` with `std::move(i)`.

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

>    > > -3- Mandates: `Uu.base()` is well-formed and convertible to `Iterator`.

>    > > -4- Effects: Constructs a `move_iterator`, i Initializes ing `current` with `u.base()`.

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

>    > > -5- Mandates: `U` is convertible to `Iterator` `u.base()` is well-formed and `is_assignable_v<Iterator&, const U&>` is `true`.

>    > > -6- Effects: Assigns `u.base()` to `current`.

[2020-02-14; Prague]

LWG Review. Some wording improvements have been made and lead to revised wording.

[2020-02-16; Prague]

Reviewed revised wording and moved to Ready for Varna.

[2020-07-17; superseded by 3435]

[2020-11-09 Approved In November virtual meeting. Status changed: Ready → WP.]

Proposed resolution:

This wording is relative to N4849.

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

   >     constexpr move_iterator();

   > > -1- Effects: Constructs a `move_iterator`, v Value-initializes ing `current`. Iterator operations applied to the resulting iterator have defined behavior if and only if the corresponding operations are defined on a value-initialized iterator of type `Iterator`.

   >     constexpr explicit move_iterator(Iterator i);

   > > -2- Effects: Constructs a move_iterator, i Initializes ing `current` with `std::move(i)`.

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

   > > -3- Mandates: `Uu.base()` is well-formed and convertible to `Iterator`.

   > > -4- Effects: Constructs a `move_iterator`, i Initializes ing `current` with `u.base()`.

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

   > > -5- Mandates: `U` is convertible to `Iterator` `u.base()` is well-formed and `is_assignable_v<Iterator&, U>` is `true`.

   > > -6- Effects: Assigns `u.base()` to `current`.