c++ - C++ 中的右值绑定(bind)混淆

标签 c++ c++11 rvalue-reference rvalue lvalue-to-rvalue

我认为应该(大致)相同对待我的三个函数调用,但显然它们不是。我试图理解为什么三个之一无法编译 (g++ -std=c++0x)。

// Minimal example to reproduce a compile bug I want to understand.

#include <iostream>
#include <string>

using namespace std;


void bar(const string &&x) { cout << "bar: " << x << endl; }

string returns_a_string() { return string("cow"); }

int main( int argc, char *argv[] )
{
    bar(string("horse"));     // ok
    bar(returns_a_string());  // ok
    string aardvark = "aardvark";
    bar(aardvark);            // not ok, fails to compile, error in next comment
    /*
      rvalue-min.cpp:29:22: error: cannot bind ‘std::string {aka std::basic_string<char>}’ lvalue to ‘const string&& {aka const std::basic_string<char>&&}’
      rvalue-min.cpp:10:6: error:   initializing argument 1 of ‘void barR(const string&&)’
    */
}

这个问题有点像 C++0x rvalue references - lvalues-rvalue binding , 但是,如果它在那里得到回答,我很抱歉,我无法提炼出来。

我想要的是能够使用任何类型的字符串调用我的函数 bar() 并让它正常工作。定义 void barR(const string &x) 就足够了,但我真的很想了解原因。

非常感谢您帮助理解为什么第三次调用不同。

最佳答案

右值引用参数的目的是专门检测对象何时为右值。因为如果一个对象是一个右值,那么函数就知道它不会被再次使用,所以它可以用它做任何它想做的事。如果左值可以绑定(bind)到右值引用,那就意味着我所说的检测实际上并没有发生。

如果要将左值传递给这些函数之一,则需要使用 std::move。通过 std::move 将一个对象传递给一个接受右值引用的函数就像在说,“这里,拿这个对象,把它的内脏撕掉,我不在乎它会发生什么".

就您的目的而言,正确答案是使参数成为常量引用。 r 值很高兴绑定(bind)到 const 引用。除了移动构造函数,制作右值引用参数几乎从来都不是正确的做法。

关于c++ - C++ 中的右值绑定(bind)混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8851661/

相关文章:

c++ - 为什么最小 MFC 项目在 Visual Studio 2013 上有链接错误?

c++ - OpenCV:对 RGB 图像应用操作(拆分+合并)

c++ - fatal error C1016 : #if[n]def expected an identifier

c++ - 在函数返回类型中返回右值引用与按值返回

c++ - 带有 std::conditional 的模板函数自动返回类型

c++ - 在不更改函数中的对象时将对象或指针作为值传递

c++ - 如何在 constexpr 函数中强制出现编译错误,而不是让它衰减到非 constexpr 上下文中?

c++ - 嵌套 for 循环和重复迭代器

c++ - 解析两种格式的文件并解析行

c++ - 按值返回的右值引用参数是 xvalue 吗?