Reputation: 485
From what I've read regarding emplace
vs push
for STL containers, the benefit of emplace
over push
is only evident when the object you're emplacing is an r-value and a non-POD type. Is this the only situation in which emplace
is faster?
Upvotes: 0
Views: 320
Reputation: 473577
The emplace
functions are meant for inserting into a container an object that does not exist yet. That is, at the site where you're considering using emplace
, you should have the parameters to an object's constructor, and thus you are choosing between insert/push_back(Typename(...))
and emplace/_back(...)
, where ...
are the arguments to the constructor.
If the object you're dealing with already exists (whether an lvalue or an rvalue), then which you choose doesn't actually matter. You'll have to copy/move from it, and both alternatives can handle those cases just fine.
The utility of in-place construction really has nothing to do with whether the type is trivial, POD, or move-only. It's all about constructing the object in-place. And if you have the ability to do in-place construction (ie: you don't have an object yet), you should prefer to do that.
Given some container of BigObject
, emplace_back(args)
will be better than push_back(BigObject(args))
. This is not a function of BigObject
's movement capabilities or triviality or being POD. This is a function of BigObject
being big; that is, sizeof(BigObject)
is significant. As such, the cost of copying/moving could be significant, so constructing it in-place makes more sense than passing it as a parameter.
And no, guaranteed elision doesn't help. push_back
gives a name to its parameter, so it stops being a prvalue inside of push_back
. As such, it must materialize the temporary, then copy/move it into the container's object.
Upvotes: 4