Skip to content

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

@t3nsor

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions