Reputation: 525
According to c++ standard,
[over.best.ics]
4 However, if the target is
(4.1) — the first parameter of a constructor or
(4.2) — the implicit object parameter of a user-defined conversion function
and the constructor or user-defined conversion function is a candidate by
(4.3) — 13.3.1.3, when the argument is the temporary in the second step of a class copy-initialization, or
(4.4) — 13.3.1.4, 13.3.1.5, or 13.3.1.6 (in all cases),
user-defined conversion sequences are not considered. [ Note: These rules prevent more than one user-defined conversion from being applied during overload resolution, thereby avoiding infinite recursion. — end note ]
struct Y { Y(int); };
struct A{operator Y();};
Y y1 = A(); //[[ 1 ]]but this compiles, why this use-defined conversion sequence is considered?
in line [[ 1 ]], it's obvious that a "A->A->Y->Y" user defined conversion sequence is used here. A->A is identity conversion A->Y is conversion function, Y->Y is identity conversion.
Upvotes: 3
Views: 287
Reputation: 60979
I assume you saw the first example (and modified it):
struct Y { Y(int); };
struct A { operator int(); };
Y y1 = A(); // error: A::operator int() is not a candidate
The crux is that invoking the converting constructor for int -> Y
constitutes a user-defined conversion, but Y -> Y
[const&
] does not. [over.best.ics]/6:
When the parameter has a class type and the argument expression has the same type, the implicit conversion sequence is an identity conversion.
I.e. in your code, there is one sole user-defined conversion sequence, not two; It consists of two standard conversion sequences (being identity conversions) and the intermediate user-defined conversion A -> Y
. You could also have returned a subclass:
struct X{}; struct Y : X {};
struct A { operator Y(); };
X y = A();
…now the second standard conversion sequence has Conversion Rank - [over.best.ics]/6 again:
When the parameter has a class type and the argument expression has a derived class type, the implicit conversion sequence is a derived-to-base Conversion from the derived class to the base class. […] A derived-to-base Conversion has Conversion rank (13.3.3.1.1).
Upvotes: 1