Can I reuse an rvalue reference parameter to return an rvalue reference?

c++, c++11, operator-overloading, rvalue-reference

Solution

The example you are looking for is a range-based `for` statement:

MyString a, b, c;
for( MyCharacter mc : a + b + c ) { ... }

In this case the result of `a + b + c` is bound to a reference, but the nested temporary (generated by `a + b` and returned as an rvalue reference by `(a + b) + c`) is destroyed before the range-based for loop is executed.

The standard defines range-based for loops in

6.5.4 The range-based for statement [stmt.ranged]

1 For a range-based `for` statement of the form

`for (`for-range-declaration`:`expression`)`statement

let range-init be equivalent to the expression surrounded by parentheses

`( expression )`

and for a range-based `for` statement of the form

`for (`for-range-declaration`:`braced-init-list`)`statement

let range-init be equivalent to the braced-init-list. In each case, a range-based `for` statement is equivalent to

{
   auto && __range = range-init;
   for ( auto __begin = begin-expr,
              __end = end-expr;
         __begin != __end;
         ++__begin ) {
      for-range-declaration = *__begin;
      statement
   }
}

Note that `auto && __range = range-init;` would extend the lifetime of a temporary returned from range-init, but it does not extend the lifetime of nested temporaries inside of range-init.

Problem

Consider the following code: ``` struct MyString { // some ctors MyString& operator+=( const MyString& other ); // implemented correctly }; MyString operator+( const MyString& lhs, const MyString& rhs ) { MyString nrv( lhs ); nrv += rhs; return nrv; } MyString&& operator+( MyString&& lhs, const MyString& rhs ) { lhs += rhs; return std::move( lhs ); // return the rvalue reference we received as a parameter! } ``` This works for the following use-case ``` MyString a, b, c; // initialized properly MyString result = a + b + c; ``` But it creates a dangling reference for ``` const MyString& result = a + b + c; ``` Now, I understand why that is and how to fix it (returning an ravlue instead of an rvalue reference) but I consider it a usage error if someone writes the above as the code looks like it is asking for trouble. Is there any "canonical" real-world example where the above operator returning a rvalue reference is a problem? What is a convincing reason why I should always return an rvalue from operators?

Original source