c++rvo

In c++, how to return multiple objects and nevertheless benefit from RVO


My function needs to return several large containers. To achieve this, the return statement creates a tuple consisting of the containers to return. However, based on my tests (using Apple clang version 11.0.0, clang-1100.0.33.17), copies are made, presumably when the tuple is constructed. In the calling function, the returned tuple is assigned using structured bindings to several variables.

If my function returned only one container, RVO would be used, and no copies would be made. Is there a nice way to similarly avoid creating copies when a function returns several containers?

Example below:

#include <tuple>
#include <vector>
using namespace std;

tuple<vector<int>, vector<double>> f(){
  vector<int> a(1);
  vector<double> b(1);
  return tuple(a,b);
}

int main(){
  auto [x, y] = f();
}

Solution

  • What if you try moving?

    tuple<vector<int>, vector<double>> f(){
      vector<int> a(1);
      vector<double> b(1);
      return tuple(std::move(a), std::move(b));
    }
    

    Or more simply, construct the tuple from temporaries (which should also lead to move construction):

    using vector_tuple = tuple<vector<int>, vector<double>>;
    
    vector_tuple f(){
      return std::make_tuple<vector_tuple>(vector<int>(1), vector<double>(1));
    }