[英]Why is this user-defined conversion failing?
这段代码失败了,但我认为选择的转换函数应该是operator std::string()
因为它比operator const char*()
( Foo -> const char* -> std::string
需要更少的步骤( Foo -> std::string
) Foo -> 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.