6

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.

keelar
  • 5,814
  • 7
  • 40
  • 79
  • See also [Why assign a return value to a reference?](https://stackoverflow.com/questions/4684646/why-assign-a-return-value-to-a-reference) – bobobobo Nov 06 '21 at 02:45

2 Answers2

6

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.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
  • Oh yes, they are not assignments, they create things instead. Thank you very much for pointing out my mistake and providing valuable answer! – keelar Feb 11 '14 at 20:19
  • So the second one won't save any operation (such as copy) at all? Originally I thought the second one just simply takes that returns from `f()` without creating a new thing. Can I know where I might wrong / miss here? – keelar Feb 11 '14 at 20:49
  • 1
    @keelar You're correct, there will be no copy. It just binds a reference to the object that is returned. But chances are, there will be no copy with the first either. – Joseph Mansfield Feb 11 '14 at 23:19
  • Thank you for further explaining this. So why and how does the first case avoid the copy? Does it rely on the implementation of `X`'s `=` operator? – keelar Feb 12 '14 at 07:08
  • 1
    @keelar Neither case uses `operator=` because they're not assignment. Nonetheless, the reason the first case would avoid a copy is because the C++ standard explicitly allows compilers to omit copies in certain cases (this is one of them). Look up copy elision. – Joseph Mansfield Feb 12 '14 at 09:41
5
  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.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084