3265. move_iterator's conversions are more broken after P1207

Section: 24.5.4.4 [move.iter.cons] Status: C++23 Submitter: Casey Carter Opened: 2019-08-23 Last modified: 2023-11-22

Priority: 2

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

View all issues with C++23 status.

Discussion:

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

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:

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

Previous resolution [SUPERSEDED]:

This wording is relative to N4830.

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

    constexpr move_iterator();
    

    -1- Effects: Constructs a move_iterator, vValue-initializesing 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, iInitializesing 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, iInitializesing current with u.base().

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

    -5- Mandates: U is convertible to Iteratoru.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 24.5.4.4 [move.iter.cons] as indicated:

    constexpr move_iterator();
    

    -1- Effects: Constructs a move_iterator, vValue-initializesing 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, iInitializesing 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, iInitializesing current with u.base().

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

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

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