c++implicit-conversionstdstringchar-pointerobject-construction

Why can compiler only implicitly convert char * to std::string in some cases


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.


Solution

  • 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