User-defined implicit conversion operator and overload resolution

c++

Solution

`uint64_t` conversion is preferred. The reason is simply that `<<` is overloaded as template for `strings` (basic_strings). Compilers will always prefer exact match over templates on overload resolution.

Problem

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 ?

Original source

Related problems