此代码失败,但我认为所选的转化函数应为operator std::string()
,因为它比Foo -> std::string
(operator const char*()
)所需的步骤少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.
答案 0 :(得分:3)
要仅使用非显式构造函数和用户定义的转换,您应该s2
foo
std::string s2 = foo;
而不是copy-initializing。{引自direct initializing
直接初始化比复制初始化更宽松:复制初始化仅考虑非显式构造函数和用户定义的转换函数,而直接初始化则考虑所有构造函数和隐式转换序列。
试试这个:
std::string
您现有的代码正在调用Foo
的构造函数,其对象类型为foo
。由于从std::string
到多个{{1}}构造函数的参数类型的有效转换具有相同的转换序列长度,因此会遇到模糊问题。
答案 1 :(得分:1)
嗯,两次转化都需要一个步骤:
foo
- &gt; char const*
使用std::string::string(char const*)
foo
- &gt; std::string
使用std::string::string(std::string&&)
第三个重载是需要考虑的选项重载结果,但是采用std::string&&
的构造函数比采用std::string(std::string const&)
的构造函数更好,如果它们是唯一的选项,则会选择它。 / p>
目前我无法轻松测试它,但我希望
std::string s3 = foo;
希望通过std::string
转换。
答案 2 :(得分:0)
错误很清楚。生成错误的行包含std::string
实例的构造函数,该实例具有使用const char*
和std::string&
复制构造函数的有效构造函数。两者都需要使用您提供的转换过载进行单个隐式转换步骤,因此它的含义是模糊的。
明确地转换对象以调用预期的转换 - 根据您的内部逻辑,const char*
构造函数可能更便宜&#39;,因为std::string
转换可能只返回{{1无论如何。如果是这种情况,我甚至建议删除std::string((const char*)this)
转换器,因为它总是会导致模糊性,而这种模糊性永远不会更高效。