Today I experienced an interesting behaviour with user-defined implicit conversion operators.
Let's take this piece of code:
struct Widget {
Widget(uint64_t) {
}
Widget(const std::string &) {
}
operator uint64_t() {
return static_cast<uint64_t>(123456789UL);
}
operator std::string() {
return std::string("Hello");
}
};
A basic struct which can implicitly be converted to either a uint64_t or a std::string.
Now, try to print out a Widget instance through std::cout :
#include <iostream>
int main() {
using std::cout;
Widget w(123456);
cout << w;
}
For whatever reason, the Widget will always be converted to a uint64_t. At first I would expect the call to be ambiguous, and be qualifed with a standard explicit conversion to compile :
int main() {
using std::cout;
Widget w(123456);
cout << static_cast<uint64_t>(w);
}
But for a reason I'm ignoring right now, operator uint64_t is selected. I tried to look at the C++ specification, but couldn't find anything useful to answer my question.
Can anyone help me figuring out what is the compiler doing with overload resolution ?