This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 116a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-12-19
Consider:
struct T { T(T&&); }; struct U { explicit operator T&&(); }; int main() { T t(U{}); }
To perform the direct-initialization of t using the move constructor of T, we have to find an implicit conversion sequence from U to T&&, which is covered by 9.4.4 [dcl.init.ref] bullet 5.3.2. The corresponding overload resolution in 12.2.2.7 [over.match.ref] paragraph 1 specifies:
The permissible types for non-explicit conversion functions are the members of R where “cv1 T” is reference-compatible (9.4.4 [dcl.init.ref]) with “cv2 T2”. For direct-initialization, the permissible types for explicit conversion functions are the members of R where T2 can be converted to type T with a (possibly trivial) qualification conversion (7.3.6 [conv.qual]); otherwise there are none.
However, the reference in question is not direct-initialized (the first parameter of the constructor is copy-initialized), thus the explicit conversion function is not considered. However, all implementations agree that the example is valid.
Subclause 12.2.2.5 [over.match.copy] paragraph 1.2 already handles this case for passing values.
Suggested resolution:
Change in 12.2.2.7 [over.match.ref] paragraph 1 as follows:
... The permissible types for non-explicit conversion functions are the members of R where “cv1 T” is reference-compatible (9.4.4 [dcl.init.ref]) with “cv2 T2”. For direct-initialization, and for copy-initialization of the first parameter of a constructor where the constructor is called with a single argument in the context of direct-initialization of an object of type "cv3 T", the permissible types for explicit conversion functions are the members of R where T2 can be converted to type T with a (possibly trivial) qualification conversion (7.3.6 [conv.qual]); otherwise there are none.