0

After asking dummy questions yesterday, experimenting, and reading quite a bunch about emplace_back over push_back, I'm still not really sure which one I should use "by default", meaning most of the time.

As was pointed out in the answer to popular question "Why would I ever use push_back instead of emplace_back?" and in other articles, the first impression people got after introducing emplace_back that "it can do anything that push_back (insert) can do and sometimes can do it better" is wrong.

So far, I have an impression that in cases where I'm using move semantics (or if I need to make I copy), where I can't benefit from the in-place object creation, and when I don't need the return value, it would be safer to use push_back not to run into troubles I can get with explicit constructor described in the links, and probably some more.

Simply saying, if I'm not using new features that emplace_back has and push_back/insert doesn't, I better stick with the push_back/insert.

Am I correct, or am I again missing something?

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
DoehJohn
  • 201
  • 1
  • 8
  • 4
    The rule is pretty simple. If you have an object you are adding to the vector. Use push or emplace, they'll do the same thing. If you have arguments to create an object, instead of creating it and calling push or emplace, call emplace with those parameters so you only get a single object construction. – NathanOliver May 26 '20 at 17:15
  • @drescherjm emplace_back has return value only since C++17 – DoehJohn May 26 '20 at 17:19
  • If you only want to call implicit constructors, then use `push_back`. – Eljay May 26 '20 at 17:19
  • @NathanOliver as described in the "Why would I ever use push_back instead of emplace_back?" answer using emplace_back in some cases leads to a bugs because of the calls to explicit constructors. – DoehJohn May 26 '20 at 17:22
  • "only since C++17" - Which you *totally should be using*. – Jesper Juhl May 26 '20 at 17:24
  • @DoehJohn Using any code incorrectly can lead to bugs. You still need to understand what you are doing. In that answers example, they should have be using `make_unique` at the call site and they would not have had any issues. – NathanOliver May 26 '20 at 17:26
  • 1
    Does this answer your question? [push\_back vs emplace\_back](https://stackoverflow.com/questions/4303513/push-back-vs-emplace-back) – Abhishek Bhagate May 26 '20 at 17:35
  • 2
    you already correctly quote from the other Q&A that emplace can do every thing that pushback can (and more). I heard someone promoting the use of push_back for clarity when emplace is not needed but that is purely opinion-based – 463035818_is_not_an_ai May 26 '20 at 17:45
  • Here's a [cppcon talk](https://youtu.be/oTMSgI1XjF8?t=17m49s) expressing an opinion on this... – rustyx May 26 '20 at 18:40
  • @rustyx I don't know who this guy is but he seems to say the same though I had ) – DoehJohn May 26 '20 at 21:44
  • @idclev463035818 I quoted it to say that it's wrong, as why it's wrong is showed in the links.. – DoehJohn May 26 '20 at 21:45
  • if you refer to the implicit vs explcit constructor difference mentioned in the top answer, then you can still get the same with `emplace_back` if you just go back to first creating an instance, see [here](https://godbolt.org/z/DW9Nm8). The answer correctly says that **accidentally** you can do something unwanted, but if you are aware of this difference and you do not want to call explicit constructors then you can do so, also with `emplace_back`. I know my example is a little silly, my point is just that `push_back` doesn't do something that you could not also get with `emplace` – 463035818_is_not_an_ai May 26 '20 at 21:58
  • btw I really first misread your question and I am still convinced that `emplace_back` can do all that `push_back` can. Maybe there is something I am missing, but not using explicit constructors isnt a showstopper – 463035818_is_not_an_ai May 26 '20 at 21:59
  • @idclev463035818 so far my understanding is that yes, emplace_back can do all push_back can do but also more, and sometimes because of that more you can get troubles, so if you don't need the power of emplace_back it's safer to use push_back – DoehJohn May 26 '20 at 23:13
  • the example with `std::addressof(a)` is an error, whether you use `push_back` or `emplace` and getting a compiler error is of course better than a runtime error. Imho the more convincing case against using `emplace` always is `std::vector{}.emplace_back(A(1,2));`. Accidentally making a copy is much easier to detect in code when you use `push_back` when you need to copy. However, as I said before, it is a matter of choice and purely opinion-based – 463035818_is_not_an_ai May 27 '20 at 07:45

0 Answers0