为什么编译器在某些情况下只能隐式地将char*转换为std :: string

joh*_*ers 3 c++ stdstring object-construction implicit-conversion char-pointer

这些工作:

struct WithString {
  WithString(std::string){};
};

void takeString(std::string){}

//implicit conversions:
takeString("hello");
WithString("hello");
Run Code Online (Sandbox Code Playgroud)

但这不是:

WithString makeWithString() { return "hello";}

// error: no viable conversion from returned value of type 'const char [6]'...
Run Code Online (Sandbox Code Playgroud)

如果std::string在前两种情况下隐式转换为"hello" ,为什么不能在最后一种情况下呢?请注意,我没有将WithString构造函数指定为explicit,所以我希望这样的转换.

通过这样做,我可以让行为起作用:

struct WithString {
  WithString(std::string){};
  WithString(const char *){};
};
Run Code Online (Sandbox Code Playgroud)

我只是对这种奇怪感到好奇.如果我假定一个猜测,我会说这是因为前两个工作的情况下,转换之间const char *std::string,但在错误的情况下,这反而会需要2转换链,首先从const char *std::string,然后从std::stringWithString.也许这就是原因,但我不确定.

Lig*_*ica 5

我想说这是因为在前两个工作情况下,转换是在const char*到std :: string之间,但在错误的情况下,这将需要一个2转换链,首先从const char*到std: :string,然后从std :: string到WithString.也许这就是原因,但我不确定.

究竟.

没有你的const char*构造函数重载,这:

WithString makeWithString() { return "hello";}
Run Code Online (Sandbox Code Playgroud)

需要两个用户定义的隐式转换; 一对一到std::string另一对WithString.这是不可能的.

但是,这里只有一个隐式转换(to std::string):

takeString("hello");
Run Code Online (Sandbox Code Playgroud)

这里也是如此,因为随后的"转换" WithString是明确的:

WithString("hello");
Run Code Online (Sandbox Code Playgroud)

通过这样做,我可以让行为起作用:

struct WithString {
  WithString(std::string){};
  WithString(const char *){};
};
Run Code Online (Sandbox Code Playgroud)

是的,这就是你应该做的.