C++ 为什么我的类的复制初始化不能与使用字符串文字的string_视图一起工作?
我有以下代码:C++ 为什么我的类的复制初始化不能与使用字符串文字的string_视图一起工作?,c++,initialization,copy-initialization,C++,Initialization,Copy Initialization,我有以下代码: #include <string_view> class Foo { public: Foo(std::string_view) {} }; 但是,如果使用复制初始化,则会失败: Foo f = "testing"; 诊断: prog.cc:15:9: error: no viable conversion from 'const char [8]' to 'Foo' Foo f = "testing"; ^ ~~~~~~~~
#include <string_view>
class Foo
{
public:
Foo(std::string_view) {}
};
但是,如果使用复制初始化,则会失败:
Foo f = "testing";
诊断:
prog.cc:15:9: error: no viable conversion from 'const char [8]' to 'Foo'
Foo f = "testing";
^ ~~~~~~~~~
prog.cc:7:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'const char [8]' to 'const Foo &' for 1st argument
class Foo
^
prog.cc:7:7: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'const char [8]' to 'Foo &&' for 1st argument
class Foo
^
prog.cc:10:5: note: candidate constructor not viable: no known conversion from 'const char [8]' to 'std::string_view' (aka 'basic_string_view<char>') for 1st argument
Foo(std::string_view) {}
^
1 error generated.
prog.cc:15:9:错误:从“const char[8]”到“Foo”没有可行的转换
Foo f=“测试”;
^ ~~~~~~~~~
prog.cc:7:7:注意:候选构造函数(隐式副本构造函数)不可行:没有已知的第一个参数从“const char[8]”到“const Foo&”的转换
福班
^
prog.cc:7:7:注意:候选构造函数(隐式移动构造函数)不可行:没有已知的第一个参数从“const char[8]”到“Foo&&”的转换
福班
^
prog.cc:10:5:注意:候选构造函数不可行:第一个参数没有从“const char[8]”到“std::string_view”(也称为“basic_string_view”)的已知转换
Foo(std::string_view){}
^
生成1个错误。
查看,我没有看到任何使用char const[]
的重载,这可能是问题所在吗?我意识到我可以使用“testing”sv
来解决这个问题,但我觉得string-literal的情况也应该可以
为什么复制初始化案例不起作用?如何使其与字符串文字一起工作?Foo f=“testing”代码>是,它要求从“testing”
(类型为const char[8]
)隐式转换为Foo
<代码>“测试”
可能会衰减为常量字符*
,然后仍然需要两个用户定义的转换。从const char*
到std::string\u视图
的转换,以及从std::string\u视图
到Foo
的转换。但在一个隐式转换序列中只允许一个用户定义的转换
Foo f(“测试”)代码>是,其行为不同<代码>“测试”
衰减为const char*
,然后转换为std::string\u view
,它用作Foo
构造函数的参数,直接初始化f
此外,复制初始化中的隐式转换必须直接从初始值设定项生成T,而例如,直接初始化要求从初始值设定项隐式转换为T的构造函数的参数
隐式转换是根据复制初始化定义的:如果T类型的对象可以用表达式E进行复制初始化,则E隐式转换为T
作为解决方法,如果您希望坚持复制初始化,可以减少所需的用户定义转换。正如您所展示的,应用
Foo f=“testing”sv是一个好主意代码>,或Foo f=std::string_视图(“测试”)
,具有相同的效果。Foo f={“testing”}代码>工作。初始化是一个混乱的C++,有十几种类型的初始化,真的应该只是一个imo。问:你有一个通用代码。你用什么:ta=init
,ta(init)
,ta{init}
,ta={init}
,ta=T(init)
,ta=T{initi}
,auto a=T(init)
,auto a=T{init code>,auto a=T(init)
?甚至专家们对此也没有答案(好吧,他们确实将答案缩小到2或3个选项,但仍然…)@bolov我在为自己叹息,因为现在我读了你的答案,这让我意识到我已经知道了这一点,但却忘了它。我的大脑想忽略复杂性,专注于直觉。但由于大量的技术细节,我们无法得到直观的结果。这令人沮丧。谢谢你的回答和提醒。
prog.cc:15:9: error: no viable conversion from 'const char [8]' to 'Foo'
Foo f = "testing";
^ ~~~~~~~~~
prog.cc:7:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'const char [8]' to 'const Foo &' for 1st argument
class Foo
^
prog.cc:7:7: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'const char [8]' to 'Foo &&' for 1st argument
class Foo
^
prog.cc:10:5: note: candidate constructor not viable: no known conversion from 'const char [8]' to 'std::string_view' (aka 'basic_string_view<char>') for 1st argument
Foo(std::string_view) {}
^
1 error generated.