Consider the following code:
struct Foo
{
typedef bool (*fptr_t)(int);
operator fptr_t() const
{
return _func;
}
fptr_t _func;
};
class Wrapper
{
public:
Wrapper(const Foo&) {}
};
void foo(bool b)
{
}
void foo(Wrapper w)
{
}
int main()
{
Foo f;
foo(f);
}
Which doesn't compile with an "ambiguous call to overloaded function" error.
As I see it, both foo
overloads would require a user-defined conversion. However for the Wrapper
version, the conversion goes
Foo->(user-defined conversion)Wrapper = exact match
while for the bool
version the conversion goes
Foo->(user-defined conversion)fptr_t->(implicit conversion)bool = exact match
which requires an additional step. Furthermore, cppreference states (although I couldn't find the exact paragraph of the standard)
If two conversion sequences are indistinguishable because they have the same rank, the following additional rules apply: 1) Conversion that does not involve pointer to bool or pointer-to-member to bool is better than the one that does.
which also seems to be the case here. So why is this call still ambiguous?
Both conversion sequences are user-defined conversion sequences.
User-defined conversion sequences that contain different constructors/conversion functions are always considered ambiguous, no matter whether additional standard conversion sequences in the user-defined conversion sequence differ in rank.