Consider the simple code :
struct A;
struct B {
B(){}
B(A const&){ }
};
struct A {
operator int() const {return 0;};
};
void func(B){}
void func(char){}
int main()
{
func(A()); //ambiguous call oO
}
First of all I'm not sure if I understand everything correctly, so correct me anytime you find me wrong please.
My understanding was that that void func(B)
should have been chosen, since argument to func
is A
which is class type, hence type of conversion required is "User defined conversion sequence"
Now from IBM C++ ref :
A user-defined conversion sequence consists of the following:
- A standard conversion sequence
- A user-defined conversion
- A second standard conversion sequence
Now there are two user defined conversion present
B::B(const A&)
and A::operator int (const A&);
so the sequence are
-> A()
-> B::B(const A&)
-> Standard conversion (identity conversion)
-> A()
-> A::operator int (const A&)
-> Standard conversion (integral conversion)
since integral conversion is worse than identity conversion I thought void func(B)
would called but still the call is ambiguous .
So please help me at which point am I wrong and why the call is ambiguous. Thanks a lot :)
The two conversion sequences here, A -> B
and A -> int
are both user-defined because they operate via functions which you defined.
The rule for ranking user-defined conversion sequences is found in 13.3.3.2 (N3797):
User-defined conversion sequence
U1
is a better conversion sequence than another user-defined conversion sequenceU2
if they contain the same user-defined conversion function or constructor or they initialize the same class in an aggregate initialization and in either case the second standard conversion sequence ofU1
is better than the second standard conversion sequence ofU2
These two conversion sequences don't contain the same user-defined conversion function, and they don't initialize the same class in aggregate initialization (since one initializes int
).
So it is not true that one sequence ranks above the other, therefore this code is ambiguous.