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



这些工作:

struct WithString {
  WithString(std::string){};
};
void takeString(std::string){}
//implicit conversions:
takeString("hello");
WithString("hello");

但这不会:

WithString makeWithString() { return "hello";}
// error: no viable conversion from returned value of type 'const char [6]'...

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

我可以通过这样做来使行为工作:

struct WithString {
  WithString(std::string){};
  WithString(const char *){};
};

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

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

完全。

如果没有您的const char*构造函数重载,这将:

WithString makeWithString() { return "hello";}

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

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

takeString("hello");

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

WithString("hello");

我可以通过这样做来使行为工作:

struct WithString {
  WithString(std::string){};
  WithString(const char *){};
};

是的,这是你应该做的。

您的方法:

WithString makeWithString() { return "hello";}

需要两个转换:隐式const char * -to- std::string转换,然后是WithString对象的构造。C++最多允许其中之一隐式发生。另请参阅此处的讨论:

返回值上的非常量复制构造函数和隐式转换

读取C++标准中的隐式转换部分。我在VS 2015中尝试了以下代码,并且编译时没有错误。

#include <string>
struct WithString {
    WithString(std::string) {};
};
void takeString(std::string) {}
//implicit conversions:
void someFunc()
{
    takeString("hello");
    WithString("hello");
    WithString t = "hello";
}
WithString makeWithString() { return "hello"; }

VS2015 似乎不正确(将从 const char* 到字符串的转换视为标准转换)。以下代码应根据标准工作,但在VS2015中产生错误:

WithString makeWithString() { return "hello"s; }
WithString t = "hello"s;

另请参阅复制初始化。在注释中,它显式调用WithString t = "hello";错误。

相关内容

  • 没有找到相关文章

最新更新