Transforming push_back(T(args, ...)) into emplace_back(args)

Hi all,

It's common to see code which does this:

  (1) V.push_back(T(args, ...));

When it could do this instead:

  (2) V.emplace_back(args, ...);

IIUC, the copy constructor for T is never called in case (2).

Would it be possible/worthwhile/correctness-preserving to perform this transformation in clang? Based on a cursory grep it doesn't seem like we do this today, but I could've missed something.


Transformation as in clang-tidy? Or as in optimization in Clang? I doubt the latter, but could imagine the former. I’m not sure if it’s a universally preferred transformation, though (but that’s one of the benefits of clang-tidy, it doesn’t have to be)

Not sure if this is “change clang itself” or “make clang do this transform”.

On the "change clang itself to use emplace_back, the general principle is that you should use push_back whenever “feasible”, and emplace_back if there is a specific reason to use that - for example non-copyable objects, or very large objects that take significant to copy construct.

If it’s “make clang do this”, I think it would be interesting to see if this can be detected and converted and how much improvement that gives for average cases - and if there are cases where it’s detrimental? Some benchmarks to show the difference would be nice.