I see a lot of code at work where people use emplace and emplace_back with a temporary object, like this:
struct A {
A::A(int, int);
};
vector v;
v
The easy answer is no; elision doesn't work with perfect forwarding. But this is c++ so the answer is actually yes.
It requires a touch of boilerplate:
struct A {
A(int, int){std::cout << "A(int,int)\n"; }
A(A&&){std::cout<<"A(A&&)\n";}
};
template
struct maker_t {
F f;
template
operator T()&&{ return f(); }
};
template
maker_t> maker( F&& f ) { return {std::forward(f)}; }
vector v;
v.emplace_back(maker([]{ return A(1,2); }));
live example.
Output is one call to A(int,int)
. No move occurs. In c++17 the making doesn't even require that a move constructor exist (but the vector does, as it thinks it may have to move the elements in an already allocated buffer). In c++14 the moves are simply elided.