This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++20 status.
Section: 25.3.3.1 [iterator.cust.move], 25.3.3.2 [iterator.cust.swap] Status: C++20 Submitter: Casey Carter Opened: 2019-10-07 Last modified: 2021-02-25
Priority: 0
View all other issues in [iterator.cust.move].
View all issues with C++20 status.
Discussion:
It is not intentional design that users may customize the behavior of
ranges::iter_move
(25.3.3.1 [iterator.cust.move]) and
ranges::iter_swap
(25.3.3.2 [iterator.cust.swap]) for pointers to program-defined
type by defining e.g. iter_move(my_type*)
or iter_swap(my_type*, my_type*)
in a
namespace associated with my_type
. The intent of customization points is that users may
define behavior for types they define, not that users may mess with the well-defined semantics for
existing types like pointers.
We should forbid such silliness by constraining the "finds an overload via ADL" cases for
customization points to only trigger with argument expressions of class or enumeration type. Note
that WG21 made a similar change to ranges::swap
shortly before merging it into the working
draft to forbid users customizing behavior for pointers to program-defined types or arrays of
program-defined types.
[2019-11-16 Issue Prioritization]
Status to Tentatively Ready and priority to 0 after seven positive votes on the reflector.
Proposed resolution:
This wording is relative to N4830.
[Drafting note: 3247(i) touches the same wording in 25.3.3.1 [iterator.cust.move]; if both are resolved simultaneously the changes should be reconciled before passing them on to the Editor.]
Modify 25.3.3.1 [iterator.cust.move] as follows:
(1.1) —
iter_move(E)
, ifthat expression is valid,E
has class or enumeration type anditer_move(E)
is a well-formed expression with overload resolution performed in a context that does not include a declaration ofranges::iter_move
.
Modify 25.3.3.2 [iterator.cust.swap] as follows:
(4.1) —
(void)iter_swap(E1, E2)
, ifthat expression is valid,eitherE1
orE2
has class or enumeration type anditer_swap(E1, E2)
is a well-formed expression with overload resolution performed in a context that includes the declarationand does not include a declaration oftemplate<class I1, class I2> void iter_swap(I1, I2) = delete;ranges::iter_swap
. If the function selected by overload resolution does not exchange the values denoted byE1
andE2
, the program is ill-formed with no diagnostic required.