Skip to content

CWG3104 [temp.deduct.conv] Deduction of T to a reference type in operator T #773

Description

@t3nsor

Full name of submitter: Thomas Mejstrik (he gave me permission to file on his behalf)

Link to Mattermost thread: https://chat.isocpp.org/general/pl/uwia7opapif4imtrk63eym98ch

Issue description: All implementations agree that T is deduced as int in the following program:

#include <type_traits> 

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

const int& x = S();

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

By analogy to the case of deduction from a call, perhaps the above deduction should simply fail because the T in operator T should never be deduced to a reference type unless its address is taken.

Suggested resolution (by Brian):

Edit [over.match.funcs.general]/7:

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 ([over.match.copy], [over.match.conv]).

Insert two bullets before [over.match.ref]/1.1:

[...] 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 ([class.member.lookup], [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 [...] The permissible types are [...]

Insert a paragraph after [temp.deduct.conv]/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 [temp.deduct.type].
If the conversion-function-id is constructed during overload resolution ([over.match.funcs]), the rules in the remainder of this subclause apply.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions