It’s very important understand there are two phrases when you return
from function. The first step is from inside fun fauto to ouside of
function ftemp(unname tempory), then fauto disappear. Then in
second step, Move from ftemp to flast. because ftemp is rvalue.
Foofun(){ returnfauto; } Fooflast=fun();
Foo f1 = fun(); When function finish, ctor is called first time, from
auto–>temp. Then, ctor is called second time, temp–>f1. With RVO, It can
be build on f1 directly, no ctor is called at all.
return reference 1: Now I will talking about return plain reference.
based on previous two explanations. You can have some conclusions
below:
Return value can use ROV and move, so It has already had high
efficiency.
You want to return a reference to avoid copy of auto obj inside of
function, but in the end you will get a dangling reference. It’s very
a dangerous action. Don’t return reference just for efficientreturn, It’s unnecessary and dangerous.
You don’t need return rvalue reference&& either. return value
ftemp outside of fun is always rvalue. ftemp->flast is move. So you
don’t need to declare Foo&& fun
If you return non-auto obj, You have to 1) new a obj, in this way,
you can return pointer directly. 2) input a reference for read, in
this way, you can input const reference, You don’t need to return
it at all. 3) input a reference for write, in this way, you don’t
need return it either, modification will act on inputted reference
directly. So when do we use return plain reference?
return reference 2: About return reference, by now, I only know three
functions which return reference. = and « are for support cascading
syntactic usage: such as cout«a«b, a=b=c. [] is for support assignment
obj[3]= 12. That is all.
operator= operator[] operator<<and>>
return reference 3: Don’t return reference or pointer to privatemember variables through you public member functions. It willbreak encapsulation.
return reference 4: If you want to return reference, there is a defensible
option that allows returning a reference and thus avoiding a temporary. But
it’s your last resort.
return reference 5: When the client programmer does something like this
and uses a reference beyond its lifetime, the bug will typically be
intermittent and very difficult to diagnose. Indeed, one of the most common
mistakes programmers make with the standard library is to use iterators
after they are no longer valid, which is pretty much the same thing as using
a reference beyond its lifetime
return rvalue reference 1: If you want to return plain reference, or rvalue
reference from a function, you have to input a plain reference or rvalue
reference first, because you can’t return any reference bound to local auto
obj.
return rvalue reference 3: below code will call move ctor once. there is some
compiler optimization here. It will not produce ftemp, use move ctor from a
to b directly.
return rvalue reference 4: below code will call move ctor once. use move ctor
from a to b directly. obj a is not intact after move. (assume that you set null
in move ctor!)
return rvalue reference 5: below code will not call move ctor at all. So you
mean that I want to keep watch for a while, and obj a is still intact right
now.
return rvalue reference 7: All the previous example, rrfun argument should
be A&& arg, I just focus on return part, so I simplify the argument to a
plain reference. But you should know, std::move(plain reference) is not good
design, here I STRONG sure that I don’t want use obj a after I use
rrfun.
return rvalue reference 8: according previous examples, we can see return
&& and value are almost the same. The important thing is you have to call
std::move inside rrfun. For this return value, if you want to copy it to b,
example 2, 3, 4 are all call move ctor once. So I prefer rrfun returnvalue, because it has clear semantic indication. example 5 only used
to keep watching for a while, and not call move ctor so obj a is still intact. I
don’t see any practical application context right now, just know about
it.
return rvalue reference 9: Why we use move in below example? lhs inside is
lvalue, not auto variable, so we need to copy it to outside ftemp. But you
can see lhs type is rvalue refence, so you can use std::move to force move it.
return rvalue reference 10: By now, I only know std::move return rvalue
reference. Function return rref is rare. A return rref can be seen below: Note
that move in this case is not optional, because ab is neither a local
automatic nor a temporary rvalue. Now, the ref-qualifier && says that the
second function is invoked on rvalue temporaries, making the following
move, instead of copy