Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rvalue reference and return value of a function

I am new to c++11 and have the following question while reading the C++11 FAQ.

Suppose we have a function f() that returns a value in type X, then we have the following ways to store its returned value:

X a = f();    // copy assignment
X&& b = f();  // move assignment

According to C++ FAQ, the second one avoids an unnecessary copy.

My question is: is the second one always the preferred way to receive the return value of a function call? In addition, is auto c = f(); equivalent to one of the above assignments? Thank you.

like image 470
keelar Avatar asked Feb 11 '14 20:02

keelar


People also ask

Is function return value an rvalue?

Returning a value from a function will turn that value into an rvalue. Once you call return on an object, the name of the object does not exist anymore (it goes out of scope), so it becomes an rvalue.

What does it mean to return by rvalue reference?

This returns a dangling reference, just like with the lvalue reference case. After the function returns, the temporary object will get destructed. You should return Beta_ab by value, like the following Beta_ab Beta::toAB() const { return Beta_ab(1, 1); }

What is an R value reference?

Rvalue references enable you to write one version of a function that accepts arbitrary arguments. Then that function can forward them to another function as if the other function had been called directly. Consider the following example that declares four types, W , X , Y , and Z .

How do rvalue references work?

An rvalue reference is formed by placing an && after some type. An rvalue reference behaves just like an lvalue reference except that it can bind to a temporary (an rvalue), whereas you can not bind a (non const) lvalue reference to an rvalue.


2 Answers

You have labelled the lines incorrectly. Neither of them are assignments, let alone copy and move assignments respectively. Instead, the first involves copy/move construction (depending on if X has a move constructor) and the second is simply initialising a reference.

The preferred way to receive the return value of a function call is the first way:

X a = f();

The copy from the temporary returned by f() into the object a will almost certainly be elided. This is the same form that auto c = f(); will take.

The second one should rarely, if ever, appear in your code. You are making an rvalue reference to the return type of f(). Stroustrup is only doing this to demonstrate that temporaries can bind to rvalue references. This occurs most often in real code when you invoke a move constructor/assignment operator, which have an rvalue reference argument type.

like image 146
Joseph Mansfield Avatar answered Sep 28 '22 00:09

Joseph Mansfield


  1. None of what you wrote is an assignment. All code pieces declare and initialize a new variable.

  2. auto a = f() is the same as X a = f()

  3. X && b is a reference, not an object.

  4. Always create a local object variable, i.e. X a = f(), never an rvalue reference. There is (almost) never a good reason for the latter. In either case you get an object that lives for as long as the variable does, and there's no need for the additional complexity.

like image 32
Kerrek SB Avatar answered Sep 28 '22 00:09

Kerrek SB