c++ - Transforming pass-by reference into pass-by return -
i have following function:
void read_int(std::vector<int> &myvector)
which allows me fill myvector
through reference. used this:
std::vector<int> myvector; read_int(myvector);
i want refactor bit code (keeping original function) in end have this:
auto myvector = read_int(); // auto std::vector<int>
what best intermediate function achieve this?
it seems me following straight-forward answer suboptimal:
std::vector<int> read_int() { std::vector<int> myvector_temp; read_int(myvector_temp); return myvector_temp; }
the obvious answer correct, , optimal.
void do_stuff(std::vector<int>& on_this); // (1) std::vector<int> do_stuff_better() { // (2) std::vector<int> myvector_temp; // (3) do_stuff(myvector_temp); // (4) return myvector_temp; // (5) }
at (3) create named return value in automatic storage (on stack).
at (5) ever return named return value function, , never return else named return value anywhere else in function.
because of (3) , (5), compiler allowed (and will) elide existence of myvector_temp
object. directly construct return value of function, , call it myvector_temp
. still needs there existing move or copy constructor, not call it.
on other end, when calling do_stuff_better
, compilers can elide assignment @ call:
std::vector<int> bob = do_stuff_better(); // (6)
the compiler allowed pass "pointer bob" , tell do_stuff_better()
construct return value in bob
's location, eliding copy construction (well, can arrange how call occurs such location do_stuff_better()
asked construct return value in same location of bob
).
and in c++11, if requirements both elisions not met, or compiler chooses not use them, in both cases move
must done instead of copy
.
at line (5) returning locally declared automatic storage duration variable in plain , simple return
statement. makes return implicit move
if not elided.
at line (6), function returns unnamed object, rvalue. when bob
constructed it, move
-constructs.
move
ing std::vector
consists of copying value of ~3 pointers, , zeroing source, regardless of how big vector
is. no elements need copied or moved.
both of above elisions, remove named local variable within do_stuff_better()
, , remove return
value of do_stuff_better()
, instead directly construct bob
, fragile. learning rules under compiler allowed elisions, , situations compiler elisions, worthwhile.
as example of how fragile, if had branch did return std::vector<int>()
in do_stuff_better()
after checking error state, in-function elision blocked.
even if elision blocked or compiler doesn't implement case, fact container move
'd means run time costs going minimal.
Comments
Post a Comment