Created on 2024-08-13.00:00:00 last changed 1 week ago
Proposed resolution (February, 2025):
Change in 9.4.4 [dcl.init.ref] bullet 5.4.1 as follows:
If T1 or T2 is a class type, user-defined conversions are considered using the rules for copy-initialization of an object of type “cv1 T1” by user-defined conversion (9.4 [dcl.init], 12.2.2.5 [over.match.copy], 12.2.2.6 [over.match.conv]); the program is ill-formed if the corresponding non-reference copy-initialization would be ill-formed. The result E of the call to the conversion function, as described for the non-reference copy-initialization, is then used to direct-initialize the reference using the form ( E ). For this direct-initialization, user-defined conversions are not considered.
Additional notes (February, 2025)
Permitting a binding of X&& to a const Y seems ill-advised; the change effected by issue 1604 in that regard is intended.
In more detail, copy-initializing a T object from a cv T prvalue succeeds:
struct X { X() = default; X(X&&) = delete; };
using CX = const X;
X x = CX(); // OK, default-initializes x
However, even with guaranteed copy elision, the pre-CWG1604 model does not handle derived classes appropriately when reference binding:
struct X { X() = default; X(X&&) = delete; }; struct Y : X {}; struct Z { operator Y() { return Y(); } }; X&& x = Z();
In this case, the rvalue reference x should bind directly to the Y materialized prvalue; there should never be an attempt to copy-initialize an X from Z to satisfy the reference binding. However, such direct reference binding would not be expected to work for a const Y prvalue.
(From submission #596.)
It is unclear whether 9.4.4 [dcl.init.ref] bullet 5.4.1 intends list-initialization or not-list-initializaiton when it talks about direct-initialization.
Furthermore, the following example was well-formed before the resolution of issue 1604 was applied:
struct X { };
struct Y : X {};
struct Z {
operator const Y () const;
};
Z z;
X&& r = z; // #1, ill-formed; was well-formed before CWG1604
Possible resolution (January, 2025) [SUPERSEDED]:
Change in 9.4.4 [dcl.init.ref] bullet 5.4.1 as follows:
If T1 or T2 is a class type, user-defined conversions are considered using the rules for copy-initialization of an object of type “cv1 T1” by user-defined conversion (9.4 [dcl.init], 12.2.2.5 [over.match.copy], 12.2.2.6 [over.match.conv]); the program is ill-formed if the corresponding non-reference copy-initialization would be ill-formed. The result E of the call to the conversion function, as described for the non-reference copy-initialization, is then used to direct-initialize the reference using the form ( E ); if E is a prvalue, its cv-qualification is adjusted to cv1. For this direct-initialization, user-defined conversions are not considered.
History | |||
---|---|---|---|
Date | User | Action | Args |
2025-03-04 13:19:59 | admin | set | messages: + msg7976 |
2025-03-04 13:19:59 | admin | set | status: open -> tentatively ready |
2025-02-25 21:32:59 | admin | set | messages: + msg7968 |
2024-08-13 00:00:00 | admin | create |