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.
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.
Exactly.
Without your const char*
constructor overload, this:
WithString makeWithString() { return "hello";}
would require two user-defined implicit conversions; one to std::string
and another to WithString
. That is not possible.
Here, though, there's only one implicit conversion (to std::string
):
takeString("hello");
And the same is true here, because the subsequent "conversion" to WithString
is explicit:
WithString("hello");
I can get the behavior to work by doing this:
struct WithString { WithString(std::string){}; WithString(const char *){}; };
Yes, that's what you should do.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With