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.