Вы можете построить векторы уже в кортеже.
tuple<vector<int>, vector<double>> f(){
tuple ret(vector<int>(1), vector<double>(1));
// Now usable by std::get<N>(ret);
auto &[a,b] = ret;
// Now you can use a and b, no copies made.
return ret;
}
Хотя это довольно похоже на другой ответ, я хотел добавить деталь со структурированным связыванием и объяснение, почему вам нужно сделать это таким или очень похожим образом, если вы хотите иметь RVO без каких-либо ходов и т. Д. c.
Для RVO компилятор в основном добавляет невидимый параметр. Он выделяет пространство, необходимое в конце для возвращаемого значения уже при вызове, и передает местоположение вызываемому объекту. Затем вызываемый будет использовать пространство для возвращаемой переменной. Следовательно, для RVO возвращаемое значение должно быть создано в функции, а следующее не делает RVO:
std::string foo(int i) {
std::string ret1{"Hi"}; // Which one should use the space?
std::string ret2{"Hello"};
if( i > 0 ) { // We only know here
return ret1;
} else {
return ret2;
}
}
Это также причина, по которой несколько возвращаемых значений должны быть частью одного и того же объекта при их создании. , Выделенное пространство точно соответствует возвращаемому типу, и вы не можете просто взять два независимых объекта и построить их в этом пространстве, даже если вы знаете, что они будут позже переданы в возвращаемом объекте.