rvalue在C ++中的绑定混淆

时间:2012-01-13 13:57:08

标签: 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, 但是,如果它在那里得到了答复,我很抱歉,我无法将它蒸馏出来。

我想要的是能够使用任何类型的字符串调用我的函数栏()并使其正常工作。这足以定义void barR(const string &x),但我真的很想理解为什么。

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

2 个答案:

答案 0 :(得分:17)

r值参考参数的目的是具体检测对象是否为r值。因为如果一个对象是一个r值,那么该函数知道它不会再被使用,所以它可以用它做任何想做的事情。如果l值可以绑定到r值引用,那就意味着我所讨论的检测实际上并没有发生。

如果要将l值传递给其中一个函数,则需要使用std::move。将一个对象通过std::move传递给一个带有r值引用的函数就像是在说,“在这里,拿出这个对象,撕掉它的内容,我不在乎它会发生什么”。

出于您的目的,正确的答案是使参数const引用。一个r值非常高兴被绑定到const引用。除了移动构造函数之外,制作r值参考参数几乎不是正确的事情。

答案 1 :(得分:5)

您需要使用std::move。这很好用:

bar(std::move(aardvark));