繁体   English   中英

为什么这个用户定义的转换失败了?

[英]Why is this user-defined conversion failing?

这段代码失败了,但我认为选择的转换函数应该是operator std::string()因为它比operator const char*()Foo -> const char* -> std::string需要更少的步骤( Foo -> std::stringFoo -> const char* -> std::string )。

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

void f(Foo foo)
{
    std::string s2(foo); // Error!
}

该标准规定转换仅限于一个转换序列,转换仅适用于明确的转换,为什么这些转换失败?

错误是:

error: call to constructor of 'std::string' (aka 'basic_string<char>') is ambiguous
    std::string s2(foo);
                ^  ~~~
note: candidate constructor
      basic_string(basic_string&& __str)
      ^
note: candidate constructor
      basic_string(const basic_string& __str);
      ^
note: candidate constructor
      basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
      ^
1 error generated.

要仅使用非显式构造函数和用户定义的转换,您应该从foo 复制初始化 s2 ,而不是直接初始化它。 引用cppreference

直接初始化比复制初始化更宽松:复制初始化仅考虑非显式构造函数和用户定义的转换函数,而直接初始化则考虑所有构造函数和隐式转换序列。

试试这个:

std::string s2 = foo;

您现有的代码正在调用std::string的构造函数,其对象类型为Foo 由于从foo到多个std::string构造函数的参数类型的有效转换具有相同的转换序列长度,因此会遇到歧义问题。

同时,双方的转换需要一个步骤:

  • foo - > char const*使用std::string::string(char const*)
  • foo - > std::string使用std::string::string(std::string&&)

第三个重载是需要考虑的选项重载结果,但是采用std::string&&的构造函数比采用std::string(std::string const&)的构造函数更好,如果它们是唯一选项则会被选中。

目前我不能轻易测试它,但我希望如此

std::string s3 = foo;

更喜欢通过std::string进行转换。

错误很清楚。 生成错误的行包含std::string实例的构造函数,该实例具有使用const char*std::string& copy构造const char*有效构造函数。 两者都需要使用您提供的转换重载进行单个隐式转换步骤,因此它的含义是模糊的。

显式地转换对象以调用预期的转换 - 取决于你的内部逻辑, const char*构造函数可能“更便宜”,因为std::string转换可能只返回std::string((const char*)this) 如果是这种情况,我甚至建议删除std::string转换器,因为它总是会导致模糊性,这种模糊性永远不会更高效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM