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

我很感兴趣,为什么它能那样工作? 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)具有move构造函数,按值void do_smth(string && s)和rvalue-reference string之间还有什么其他区别?

最佳答案

这是右值引用的重点。它们绑定(bind)到右值,而而不是绑定(bind)到左值。

这样,当您同时具有左值版本和右值版本时,可以确保调用所需的重载。例如,复制构造函数与移动构造函数。

这是一个功能。

另外,您的左值是const,即使没有使用右值引用,它也不与do_smth的签名匹配。

如果您希望do_smth能够采用任一种表达式,则使其成为const string&,或者使其成为模板并使其具有forwarding reference T&&(看起来像是右值引用,但不是)。

如果您希望do_smth存储它自己的字符串版本,然后取一个值:如果需要,您仍然可以避免复制,方法是在调用站点上使用std::move(或传递一个右值,这将触发字符串自己的move构造函数) 。

鉴于右值引用绑定(bind)规则是如何制定的,请参阅所有选项如何可用且优雅?都适合。

决定允许do_smth采取什么完全取决于它要“做什么”的“ secret ”,只有您才能说出那是什么。

关于c++ - 为什么将左值作为右值参数传递失败?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54439575/

10-13 05:02