Considere o seguinte código:
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);
}
Que não compila com um erro de "chamada ambígua para função sobrecarregada". A meu ver, ambas foo
as sobrecargas exigiriam uma conversão definida pelo usuário. Porém para a Wrapper
versão, a conversão vai
Foo->(user-defined conversion)Wrapper = exact match
enquanto para a bool
versão a conversão vai
Foo->(user-defined conversion)fptr_t->(implicit conversion)bool = exact match
o que requer uma etapa adicional. Além disso, cppreference afirma (embora eu não tenha conseguido encontrar o parágrafo exato do padrão)
Se duas sequências de conversão são indistinguíveis porque têm a mesma classificação, as seguintes regras adicionais se aplicam: 1) A conversão que não envolve ponteiro para bool ou ponteiro para membro para bool é melhor do que aquela que envolve.
o que também parece ser o caso aqui. Então, por que essa chamada ainda é ambígua?
Ambas as sequências de conversão são sequências de conversão definidas pelo usuário.
As sequências de conversão definidas pelo usuário que contêm diferentes construtores/funções de conversão são sempre consideradas ambíguas, independentemente de as sequências de conversão padrão adicionais na sequência de conversão definida pelo usuário diferirem em classificação.