Reputation: 557
I'm trying to write a function that returns a pair of objects, one of which is harder to construct than the other. This code comes close to illustrating what I'm trying:
#include<iostream>
#include<tuple>
using namespace std;
struct A {
int i;
A(A&& a): i(a.i) { cout << "move-constructing A: "<<a.i<<"\n"; }
A(int j): i(j) { cout << "int-constructing A: "<<j<<"\n"; }
};
using APair = pair<A,A>;
APair get_As() {
A a(8);
return {piecewise_construct, make_tuple(move(a)), make_tuple(10)};
}
int main()
{
APair As = get_As();
return 0;
}
But, when I run this, I see a double move of the A
constructed with 8
:
int-constructing A: 8
move-constructing A: 8
move-constructing A: 8
int-constructing A: 10
I recon that's because the A
is moved into the std::tuple
and then into the APair
of main()
. Clearly, a single move should be sufficient to construct the APair
, but I cannot see how I would do that, since the piecewise constructor seems unavoidable, which means I also have to provide a tuple... My question is thus: how can this be done with a single move of A
?
Upvotes: 1
Views: 292
Reputation: 217428
You might use std::forward_as_tuple
to avoid extra move constructor:
return {piecewise_construct, std::forward_as_tuple(move(a)), make_tuple(10)};
So you have std::tuple<A&&>
instead of std::tuple<A>
(which move construct).
Upvotes: 1