Suppose that
- I have a function
A f()
; - I want to initialize a local variable
a
to the return value off
; - I don't want to rely on RVO;
What is the best option (and why) to avoid the return value of f
being copied when
a
may have to be modified- I know that
a
will not be modified
Options:
a) A a = f();
b) A&& a = f();
c) const A& = f();
d) const A&& = f();
EDIT:
I would say:
- b)
- c)
Because both use references and avoid an extra copy (which could be avoided by RVO as well, but that is not guaranteed). So how come I see option a) suggested most of the time?
I guess the heart of the question is: I get that a) most likely has the same effect as c), so why not use c) instead of a), to make things explicit and independent on the compiler?
Because all 4 options return the value the exact same way. The only thing that changes is the way you bind a variable to the returned temporary.
a
of typeA
and move-initializes it from the temporary. This is not an assignment, this is initialization. The move constructor will be elided by any popular compiler, provided that you don't explicitly disallow it, which means that the program will just ensure that the storage reserved for the return value is the storage for thea
variable.a
which is a const-reference to the temporary, extending the lifetime of the temporary. Which means that the temporary return value gets storage, and the variablea
will refer to it. The compiler, knowing statically that the reference points to the returned value, will effectively generate the same code as a).std::move
the variable later.Now :
If
a
may be modified, use :If you know that
a
will not be modified, use :The use of
auto
will prevent any type mismatch. (and as such, any implicit conversion toA
iff
happens not to return typeA
after all. Oh, those maintainers...)If
class A
have move-constructor then just useA a = f();
If you know nothing aboutclass A
you can rely only on RVO or NRVO optimization.