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.
Section: 25.5.4.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 25.5.4.4 [move.iter.cons] were technically broken before P1207:
25.5.4.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.
25.5.4.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.
Modify 25.5.4.4 [move.iter.cons] as indicated:
constexpr move_iterator();-1- Effects:
Constructs a move_iterator, vValue-initializesingcurrent.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, iInitializesingcurrent with std::move(i).template<class U> constexpr move_iterator(const move_iterator<U>& u);-3- Mandates:
-4- Effects:Uu.base() is well-formed and convertible to Iterator.Constructs a move_iterator, iInitializesingcurrent with u.base().template<class U> constexpr move_iterator& operator=(const move_iterator<U>& u);-5- Mandates:
-6- Effects: Assigns u.base() to current.U is convertible to Iteratoru.base() is well-formed and is_assignable_v<Iterator&, const U&> is true.
[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.
Modify 25.5.4.4 [move.iter.cons] as indicated:
constexpr move_iterator();-1- Effects:
Constructs a move_iterator, vValue-initializesingcurrent.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, iInitializesingcurrent with std::move(i).template<class U> constexpr move_iterator(const move_iterator<U>& u);-3- Mandates:
-4- Effects:Uu.base() is well-formed and convertible to Iterator.Constructs a move_iterator, iInitializesingcurrent with u.base().template<class U> constexpr move_iterator& operator=(const move_iterator<U>& u);-5- Mandates:
-6- Effects: Assigns u.base() to current.U is convertible to Iteratoru.base() is well-formed and is_assignable_v<Iterator&, U> is true.