Jack  Chin
Jack Chin

Reputation: 525

why this user defined conversion sequence is not prohibited?

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

Answers (1)

Columbo
Columbo

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

Related Questions