AF_cpp
AF_cpp

Reputation: 591

Emplace_back instead of push_back on stl containers?

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.

Upvotes: 0

Views: 627

Answers (2)

user2249683
user2249683

Reputation:

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);
}

Upvotes: 3

Kerrek SB
Kerrek SB

Reputation: 477010

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.

Upvotes: 3

Related Questions