I know that when returning a local in order to keep RVO we should allow the compiler to perform move elision by returning a value like so
std::vector<double> some_func(){
std::vector<double> my_vector;
//do something
return my_vector;
}
rather than
std::vector<double> some_func(){
std::vector<double> my_vector;
//do something
return std::move(my_vector);
}
However, if we are constructing an object in a return statement, do uses of std::move
in the constructor either help, hinder, or do nothing to get efficiency or get in the compilers way?
As an example consider these two implementations
std::pair<std::vector<double>,std::vector<double> > some_func()
std::vector<double> my_vec_a;
std::vector<double> my_vec_b;
//do something
return std::make_pair(my_vec_a,my_vec_b);
}
and
std::pair<std::vector<double>,std::vector<double> > some_func()
std::vector<double> my_vec_a;
std::vector<double> my_vec_b;
//do something
return std::make_pair(std::move(my_vec_a),std::move(my_vec_b));
}
So
- In the first, will the compiler recognise that
my_vec_a
andmy_vec_b
will go out of scope and optimise the construction in the return statement? - If so will the use of
std::move
in the second prevent that optimisation? - Or will the second option be more efficient?
CodePudding user response:
This one is more efficient:
std::pair<std::vector<double>,std::vector<double> > some_func() {
std::vector<double> my_vec_a;
std::vector<double> my_vec_b;
//do something
return std::make_pair(std::move(my_vec_a),std::move(my_vec_b));
}
without the std::move
calls the two vectors are copied. The problem isn't the actual return it's that the two vectors in the pair being constructed are being constructed from lvalues; the compiler can't choose to use a move-constructor there without you explicitly telling it to via std::move
.