CWG Issue 5 (original) (raw)
This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 117a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2025-04-13
5. CV-qualifiers and type conversions
Section: 9.5 [dcl.init]Status: CD1Submitter: Josee LajoieDate: unknown
[Moved to DR at 4/01 meeting.]
The description of copy-initialization in 9.5 [dcl.init] paragraph 14 says:
If the destination type is a (possibly cv-qualified) class type:
...Otherwise (i.e. for the remaining copy-initialization cases), user-defined conversion sequences that can convert from the source type to the destination type or (when a conversion function is used) to a derived class thereof are enumerated ... if the function is a constructor, the call initializes a temporary of the destination type. ... Should "destination type" in this last bullet refer to "cv-unqualified destination type" to make it clear that the destination type excludes any cv-qualifiers? This would make it clearer that the following example is well-formed:
struct A { A(A&); }; struct B : A { };
struct C { operator B&(); };
C c; const A a = c; // allowed?
The temporary created with the conversion function is an lvalue of typeB. If the temporary must have the cv-qualifiers of the destination type (i.e. const) then the copy-constructor for A cannot be called to create the object of type A from the lvalue of type const B. If the temporary has the cv-qualifiers of the result type of the conversion function, then the copy-constructor for A can be called to create the object of type A from the lvalue of type const B. This last outcome seems more appropriate.
Steve Adamczyk:
Because of late changes to this area, the relevant text is now the third sub-bullet of the fourth bullet of 9.5 [dcl.init] paragraph 14:
Otherwise (i.e., for the remaining copy-initialization cases), user-defined conversion sequences that can convert from the source type to the destination type or (when a conversion function is used) to a derived class thereof are enumerated... The function selected is called with the initializer expression as its argument; if the function is a constructor, the call initializes a temporary of the destination type. The result of the call (which is the temporary for the constructor case) is then used to direct-initialize, according to the rules above, the object that is the destination of the copy-initialization.
The issue still remains whether the wording should refer to "the cv-unqualified version of the destination type." I think it should.
Notes from 10/00 meeting:
The original example does not illustrate the remaining problem. The following example does:
struct C { };
C c;
struct A {
A(const A&);
A(const C&);
};
const volatile A a = c; // Okay
Proposed Resolution (04/01):
In 9.5 [dcl.init], paragraph 14, bullet 4, sub-bullet 3, change
if the function is a constructor, the call initializes a temporary of the destination type.
to
if the function is a constructor, the call initializes a temporary of the cv-unqualified version of the destination type.