Title
move_iterator's conversions are more broken after P1207
Status
new
Section
[move.iter.cons]
Submitter
Casey Carter

Created on 2019-08-23.00:00:00 last changed 1 month ago

Messages

Date: 2020-02-14.15:15:22

Proposed resolution:

This wording is relative to N4849.

  1. Modify [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.

Date: 2020-02-15.00:00:00

[ 2020-02-14; Prague ]

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

Date: 2019-09-14.00:00:00

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

Previous resolution [SUPERSEDED]:

This wording is relative to N4830.

  1. Modify [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.

Date: 2019-08-23.00:00:00

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

  • [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.

  • [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.

History
Date User Action Args
2020-02-14 15:15:22adminsetmessages: + msg11128
2019-09-14 17:05:44adminsetmessages: + msg10616
2019-08-27 18:28:02adminsetmessages: + msg10586
2019-08-23 00:00:00admincreate