0

I'm not quite sure if i can always replace push_back with emplace_back.

I know emplace_back can forward the parameters to construct the object directly in the vector without copying twice (perfect forwarding etc...)

And if i do soemthing like this:

vector<A> o;
o.emplace_back(A{});

Then it should call the copy constructor of A. Correct ? So it does exactly the same as push_back. Doesn't it ?

Are there some exceptions? Are there good reasons to use push_back ? Because then it is easier to just use always emplace_back without thinking about it.

AF_cpp
  • 568
  • 5
  • 15
  • 2
    What's your question? If you wanted to take advantage of emplacing, you'd write `o.emplace_back();`. – Kerrek SB Jun 19 '15 at 16:16
  • possible duplicate of [Should I replace all calls to push\_back with emplace\_back?](http://stackoverflow.com/questions/22468837/should-i-replace-all-calls-to-push-back-with-emplace-back) – NathanOliver Jun 19 '15 at 16:16
  • After c++11 there's `push_back(value_type&& val)` so there's no need for `emplace_back` temporary `A{}`. – 101010 Jun 19 '15 at 16:17

2 Answers2

3

The main purpose of emplace is to perform explicit conversions:

#include <chrono>
#include <vector>

using namespace std::chrono_literals;

std::vector<std::chrono::seconds> time;

time.push_back(1s);     // OK
// time.push_back(1);   // Error, thank god
time.emplace_back(1);   // OK, we assume you know what you're doing

Use push_back to add an element of a given value to the container. Use emplace_back to explicitly construct an element from constructor arguments.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • Another important feature of `emplace_back`is, from http://en.cppreference.com/w/cpp/container/vector/emplace_back , *typically uses placement-new to construct the element in-place at the location provided by the container.* – R Sahu Jun 19 '15 at 16:32
  • @RSahu: Well, yes, that's what emplacing *does*, but that doesn't answer why you would want to use it. – Kerrek SB Jun 19 '15 at 18:36
3

Another application (besides the answer of Kerrek SB) for 'emplace_back' is constructing a non-copyable/non-movable object in a container:

#include <list>

class Resource
{
    private:
    int id;
    int data;

    public:
    Resource(int id, int data) : id(id), data(data) {}
    Resource(const Resource&) = delete;
    Resource& operator = (const Resource&) = delete;
};

int main() {
    std::list<Resource> resources;
    // The following will not compile:
    // resources.push_back(Resource(1, 2));
    resources.emplace_back(1, 2);
}
Community
  • 1
  • 1