2

I have code

void print(string &&str) {
   cout << str << endl;
}
int main() {
   string tmp("Hello");
   string&& str = move(tmp);
   //print(move(str));
   print(str);
   return 0;
}

After compiling I get error: cannot bind rvalue reference of type 'std::__cxx11::string&&' to lvalue of type 'std::__cxx11::string'.

But str is r-value reference to r-value(isn't it?), so passing it into print makes sense I believe. Why this error occurred?

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
Lw Cui
  • 483
  • 7
  • 15

1 Answers1

4

You're confusing with value categories and types.

(emphasis mine)

lvalue

The following expressions are lvalue expressions:

  • the name of a variable or a function in scope, regardless of type, such as std::cin or std::endl. Even if the variable's type is rvalue reference, the expression consisting of its name is an lvalue expression;
  • ...

The type of str is rvalue-reference (to string), but as a named variable it's an lvalue, which can't be bound to rvalue reference.

Consider the following case if this is allowed:

string tmp("Hello");
string&& str = move(tmp);
print(str);               // str might be moved here

cout << str << endl;      // dangerous; str's state is undeterminate

So you need to use std::move explicitly (to convert str to an xvalue) if you're sure of the effects.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405