This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++23 status.
3435.three_way_comparable_with<reverse_iterator<int*>, reverse_iterator<const int*>>
Section: 24.5.4.4 [move.iter.cons], 24.5.1.4 [reverse.iter.cons] Status: C++23 Submitter: Casey Carter Opened: 2020-04-26 Last modified: 2023-11-22
Priority: 2
View all other issues in [move.iter.cons].
View all issues with C++23 status.
Discussion:
Despite that reverse_iterator<int*>
and reverse_iterator<const int*>
are comparable with <=>
, three_way_comparable_with<reverse_iterator<int*>, reverse_iterator<const int*>>
is false
. This unfortunate state of affairs results from the absence of constraints on reverse_iterator
's converting constructor: both convertible_to<reverse_iterator<int*>, reverse_iterator<const int*>>
and convertible_to<reverse_iterator<const int*>, reverse_iterator<int*>>
evaluate to true
, despite that reverse_iterator<int*>
's converting constructor template is ill-formed when instantiated for reverse_iterator<const int*>
. This apparent bi-convertibility results in ambiguity when trying to determine common_reference_t<const reverse_iterator<int*>&, const reverse_iterator<const int*>&>
, causing the common_reference
requirement in three_way_comparable_with
to fail.
reverse_iterator
's conversion constructor (and converting assignment operator, while we're here) correctly so we can use the concept to determine when it's ok to compare specializations of reverse_iterator
with <=>
. move_iterator
has similar issues due to its similarly unconstrained conversions. We should fix both similarly.
[2020-07-17; Priority set to 2 in telecon]
[2020-07-26; Reflector poll]
Set status to Tentatively Ready after five votes in favour during reflector discussions.
[2020-11-09 Approved In November virtual meeting. Status changed: Tentatively Ready → WP.]
Proposed resolution:
This wording is relative to N4861.
Modify 24.5.4.4 [move.iter.cons] as indicated:
[Drafting note: this incorporates and supercedes the P/R of LWG 3265(i).]
constexpr move_iterator();-1- Effects: Constructs a
move_iterator
, v Value-initializ es ingcurrent
. 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 typeIterator
.constexpr explicit move_iterator(Iterator i);-2- Effects: Constructs a
move_iterator
, i Initializ es ingcurrent
withstd::move(i)
.template<class U> constexpr move_iterator(const move_iterator<U>& u);-3- Mandates:
-4- Effects: Constructs aU
is convertible toIterator
Constraints:is_same_v<U, Iterator>
isfalse
andconst U&
modelsconvertible_to<Iterator>
.move_iterator
, i Initializ es ingcurrent
withu. current base()
.template<class U> constexpr move_iterator& operator=(const move_iterator<U>& u);-5- Mandates:
-6- Effects: AssignsU
is convertible toIterator
Constraints:is_same_v<U, Iterator>
isfalse
,const U&
modelsconvertible_to<Iterator>
, andassignable_from<Iterator&, const U&>
is modeled.u. current base()
tocurrent
.
Modify 24.5.1.4 [reverse.iter.cons] as indicated:
template<class U> constexpr reverse_iterator(const reverse_iterator<U>& u);-?- Constraints:
-3- Effects: Initializesis_same_v<U, Iterator>
isfalse
andconst U&
modelsconvertible_to<Iterator>
.current
withu.current
.template<class U> constexpr reverse_iterator& operator=(const reverse_iterator<U>& u);-?- Constraints:
-4- Effects: Assignsis_same_v<U, Iterator>
isfalse
,const U&
modelsconvertible_to<Iterator>
, andassignable_from<Iterator&, const U&>
is modeled.u. current base()
tocurrent
. -5- Returns:*this
.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4