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.
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.
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); }
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 .
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.
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.
None of what you wrote is an assignment. All code pieces declare and initialize a new variable.
auto a = f()
is the same as X a = f()
X && b
is a reference, not an object.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With