不将左值引用作为右值引用参数传递。编译器可以使用其副本构造函数创建一个临时对象,并将其作为右值传递,但事实并非如此。如果类型不匹配,它仍然会调用构造函数。
我很感兴趣,为什么它能那样工作? C ++标准中的哪种设计逻辑会强制编译器以不同的方式对待复制构造函数?
void do_smth(string && s)
{}
void f(const char * s)
{
do_smth(s); // passes a temporary string constructed from const char*
}
void g(const string & s)
{
do_smth(s); // does not compile
}
void h(const string & s)
{
do_smth(string(s)); // ok again
}
如果我不想实现第二个签名do_smth(const string &)
,该怎么办?我应该改用值传递void do_smth(string s)
吗?
在对象void do_smth(string s)
具有移动构造函数的情况下,按值void do_smth(string && s)
和右值引用string
之间还有什么区别?
答案 0 :(得分:3)
这是右值引用的重点。它们绑定到 rvalues ,并且不绑定到 lvalues 。
当您同时拥有左值版本和右值版本时,这就是确保调用所需的重载的方式。例如,复制构造函数与移动构造函数。
这是一个功能。
此外,您的左值是const
,即使它没有右值引用,它也与do_smth
的签名不匹配。
如果您希望do_smth
能够采用 两种类型的表达式,请使其采用const string&
,或使其成为模板并使其采用< em> forwarding reference T&&
(看起来像是右值引用,但不是)。
如果您想让do_smth
存储其自己的字符串版本,则需要取一个值:如果需要,您仍然可以通过使用std::move
来避免复制调用网站(或通过传递右值,这将触发字符串自己的move构造函数)。
由于右值引用绑定规则是如何制定的,请参阅所有选项如何可用且优雅?都适合。
决定允许do_smth
接受什么完全取决于它要“做什么”,只有您能说出那是什么。
答案 1 :(得分:0)
中,您会给出 const 字符串的 non const 副本,因此 const 会与 g 案例
当然可以通过void do_smth(string s){...}
在调用时进行复制,并且 const 和非const字符串都可以在参数中给出