These work:
struct WithString {
WithString(std::string){};
};
void takeString(std::string){}
//implicit conversions:
takeString("hello");
WithString("hello");
But this does not:
WithString makeWithString() { return "hello";}
// error: no viable conversion from returned value of type 'const char [6]'...
If "hello" is implicitly converted to std::string
in the first two cases, why cannot it not be in the last case? Note that I did not specify the WithString
constructor as explicit
, so I'd expect such a conversion.
I can get the behavior to work by doing this:
struct WithString {
WithString(std::string){};
WithString(const char *){};
};
I'm just curious about this oddity. If I postulate a guess, I would say it is because in the first two working cases, the conversion is between const char *
to std::string
, but in the error case, this would instead require a chain of 2 conversion, first from const char *
to std::string
, and then from std::string
to WithString
. So perhaps that is the reason, but I'm not sure.
Your method:
WithString makeWithString() { return "hello";}
needs two conversions: The implicit const char *
-to-std::string
conversion, then a construction of a WithString
object. C++ allows at most one of these to happen implicitly. See also the discussion here:
Non-const copy constructor and implicit conversions on return value