user5965026
user5965026

Reputation: 485

Is emplace only advantageous over push when the object being emplaced is a non-POD and an r-value?

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

Answers (1)

Nicol Bolas
Nicol Bolas

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

Related Questions