This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 119a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2025-12-20


3104. Deduction of reference types in conversion operators

Section: 13.10.3.4  [temp.deduct.conv]     Status: open     Submitter: Thomas Mejstrik     Date: 2025-09-28

(From submission #773.)

Consider:

  #include <type_traits>

  struct S {
    template <typename T>
    operator T() {
      static_assert(std::is_same_v<int, T>);
    }
  };

  const int& x = S();

Implementations agree that T = int is the deduction result.

However, 12.2.2.1 [over.match.funcs.general] paragraph 7 specifies that operator const int& is looked up in the scope of S, and 13.10.3.4 [temp.deduct.conv] specifies that cv-qualifiers are stripped before references, resulting in A = const int, which is then compared against P = T.

Possible resolution:

  1. Change in 12.2.2.1 [over.match.funcs.general] paragraph 7 as follows:

    In each case where conversion functions of a class S are considered for initializing an object or reference of type T, the candidate functions include the result of a search for the conversion-function-id operator T in S (12.2.2.5 [over.match.copy], 12.2.2.6 [over.match.conv]). ...
  2. Change in 12.2.2.7 [over.match.ref] paragraph 1 as follows:

    ... Assuming that "reference to cv1 T" is the type of the reference being initialized, the candidate functions are selected as follows:
    • When converting to an lvalue, the candidates include the result of a search for the conversion-function-id operator cv1 T& in S (6.5.2 [class.member.lookup], 13.10.3.4 [temp.deduct.conv]).
    • When converting to an rvalue or function lvalue, the candidates include the results of searches for the conversion-function-ids operator cv1 T and operator cv1 T&& in S.
    • Let R be a set of types including
      • “lvalue reference to cv2 T2” (when converting to an lvalue) and
      • “cv2 T2” and “rvalue reference to cv2 T2” (when converting to an rvalue or an lvalue of function type)
      for any T2. The permissible types for non-explicit conversion functions are the members of R where “cv1 T” is reference-compatible (9.5.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.
  3. Insert a paragraph after 13.10.3.4 [temp.deduct.conv] paragraph 1:

    Template argument deduction is done by comparing the return type of the conversion function template (call it P) with the type specified by the conversion-type-id of the conversion-function-id being looked up (call it A) as described in 13.10.3.6 [temp.deduct.type]. If the conversion-function-id is constructed during overload resolution (12.2.2 [over.match.funcs]), the rules in the remainder of this subclause apply.

    If A is a reference type and P is not, deduction fails.