First exampleSTD::Vector<int>Return_vector(void){STD::Vector<int>tmp{1,2,3,4,5}; returntmp;}STD::Vector<int> &&Rval_ref=Return_vector();
The first example returns a temporary which is caught by rval_ref . That temporary'll has the IT life extended beyond the definition and your rval_ref can use it as if you had caught it by valu E. Very similar to the following: const std::vector<int>& rval_ref = return_vector();
Except that in my rewrite you obviously can ' t use Rval_ref in a non-const manner. Second ExampleSTD::Vector<int>&&Return_vector(void){STD::Vector<int>tmp{1,2,3,4,5}; returnSTD::Move(tmp);}STD::Vector<int> &&Rval_ref=Return_vector();
The second example you have created a run time error. Rval_ref now holds a reference to the destructed tmp inside the function. With any luck, this code would immediately crash. Third exampleSTD::Vector<int>Return_vector(void){STD::Vector<int>tmp{1,2,3,4,5}; returnSTD::Move(tmp);}STD::Vector<int> &&Rval_ref=Return_vector();
Your Third example is roughly equivalent to Your first. The Std::move on TMP are unnecessary and can actually be a performance pessimization as it would inhibit return value Optimi Zation. The best-by-code what are you ' re doing are: Best PracticeSTD::Vector<int>Return_vector(void){STD::Vector<int>tmp{1,2,3,4,5}; returntmp;}STD::Vector<int>Rval_ref=Return_vector();
i.e. just as you would in C++03. TMP is implicitly treated as a rvalue in the return statement. It'll either is returned via Return-value-optimization (no copy, no move), or if the compiler decides it can not perform RVO, then it'll use Vector's move constructor to do the return. Only if RVO are not performed, and if the returned type does not has a move constructor would the copy constructor be used For the return.
Shareeditflag |
answered "at 20:52Howard hinnant 74.1k145 251 |
|