This is basic overload resolution. Both overloads are viable:
Binding
57
tofoo::operator=(int)
(exact match)Implicitly converting
57
tofoo
via the converting constructor, and binding the temporaryfoo
object to the implicitly definedfoo::operator=(foo const &)
.
Since the latter requires more conversions than the former, it is a less-good match, and the former overload is chosen.
You can still achieve the second call by making it explicit:
f = foo(57); // binds perfectly to foo::operator=(foo const &)
The full set of rules for overload resolution are rather long and involved, but in individual cases like this the answer is straight-forward. See 13.3 ([over.match]) for the full, gory details, though.