What are the rules for type inference of a template conversion operator during initialization?

Consider this code:

struct S
{
    template <typename T>
    operator T() const
    { return {}; }
};

struct R
{
    R() = default;
    R(const R&) = default;
    R(R&&) = default;
    R(bool) {}
};

      

Where in the standard are these rules defined for the following types of behavior?

S s;
R r1 = s; // (1) passes: T = R
R r2(s);  // (2) ambiguity: T = R or bool?

      

Why doesn't (1) cause an ambiguity problem (given that it R

can be initialized as well bool

)? I recently wrote an answer to a similar question, but I'm curious why (1) doesn't behave like (2) in this context, and I don't know where this is described in the standard.

+3


source to share


1 answer


8.5 / 15-16:

An initialization that occurs in the form of an =

element or peer-to-peer condition and ... is called copy-initialization.

Initialization that happens on forms

T x(a);
T x{a};

      

and also ... is called direct initialization.



So, R r1 = s;

this is copy, and R r2(s);

is direct initialization. On clause 17:

  • If the target type is a class class (possibly cv-qualit):

    • If the initialization is direct initialization, or if it is copy-initialization, where the cv-unqualified version of the source type is the same class as or derived from the destination class, the constructors that count are. The corresponding constructors are listed (13.3.1.3), and the best one is chosen using overload resolution (13.3).

    • Otherwise (for example, for other copy initialization cases) custom conversion sequences that can convert from source type to destination type or (when a conversion function is used) to its derived class are listed as described in 13.3.1.4, and the best one is chosen with overload resolution (13.3).

So direct initialization loops through all the constructors R

and ends up in ambiguity, while copy initialization explicitly tries to directly convert the expression to R

.

+2


source







All Articles