将左值引用作为右值引用参数传递不会编译。编译器可以使用其复制构造函数创建一个临时对象并将其作为右值传递,但事实并非如此。如果类型不匹配,它仍然会调用构造函数。
我很感兴趣,为什么会这样? 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
有移动构造函数吗?
最佳答案
这就是右值引用的全部要点。它们绑定(bind)到右值,不到左值。
当您同时拥有左值版本和右值版本时,这就是您确保调用所需重载的方式。例如,复制构造函数与移动构造函数。
这是一个功能。
此外,您的左值是 const
,它与 do_smth
的签名不匹配,即使它没有采用右值引用也是如此。
如果您希望do_smth
能够采用任一种 表达式,要么使其采用const string&
,要么使其成为模板并让它采用 forwarding reference T&&
(看起来像右值引用但实际上不是)。
如果您希望do_smth
存储它自己的字符串版本,那么让它取一个值:如果需要,您仍然可以通过使用避免复制std::move
在调用点(或通过传递右值,这将触发字符串自己的移动构造函数)。
看看由于右值引用绑定(bind)规则是如何制定的,所有选项是如何可用且优雅的?这一切都适合。
决定允许 do_smth
采取什么完全取决于它要“做”什么“smth”,只有你能说出那是什么。
关于c++ - 为什么将左值作为右值参数传递失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54439575/