c++ - 为什么将左值作为右值参数传递失败?

标签 c++ rvalue-reference

将左值引用作为右值引用参数传递不会编译。编译器可以使用其复制构造函数创建一个临时对象并将其作为右值传递,但事实并非如此。如果类型不匹配,它仍然会调用构造函数。

我很感兴趣,为什么会这样? 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/

相关文章:

c++ - 临时 const 数组未绑定(bind)到右值引用

c++ - 按值传递与 const & 和 && 重载

c++ - auto&&和auto的区别

c++ - 将 argv 和 argc 传递给线程

c++ - 这不是复制初始化,是吗?

c++ - 传递常规和右值引用参数的通用宏代码

c++ - 来自右值的非常量类型引用

c++ - 直接使用 postgres JSONB

c++ - basic_string 分配器

C# : Pass string array to c++ dll/dylib