NPS
NPS

Reputation: 6355

Is there a difference between std::stack::push() and std::stack::emplace() in this case?

Look at this code:

struct Dummy
{
    int bla;
    int blabla;
    char character;

    Dummy (int b, int bb, char c)
        : bla(b), blabla(bb), character(c)
    {}
};

std::stack<Dummy> s;
Dummy dummy;
s.push(dummy);   // (1)
s.emplace(dummy);   // (2)

I fail to see the difference between (1) and (2). I know emplace() is useful when you're providing arguments for the constructor of the object being added, e.g.:

s.emplace(1, 2, 'c');

but I don't know what the difference is in the case I described because both push() and emplace() should take a reference to the local dummy object and create a new object using copy ctor or something like that. Does push() create any temporary objects in the process?

Upvotes: 4

Views: 1141

Answers (2)

Barry
Barry

Reputation: 303206

There will be no temporaries. For the standard, push looks like:

void push(const value_type& x) { c.push_back(x); }
void push(value_type&& x) { c.push_back(std::move(x)); }

Whereas emplace looks like:

template <class... Args>
void emplace(Args&&... args) { 
    c.emplace_back(std::forward<Args>(args)...);
}

Where c is the underlying container, defaulting to deque<T>. So in the former case, when you call push, you are calling push(const Dummy&) which will create a new object via Dummy(const Dummy&). In the latter case, you are calling emplace_back(Dummy&) which directly create a new object via Dummy(Dummy&).

In your case - there is no difference between these two copy constructors. They would both call the trivial copy constructor implicitly created by the compiler. So you should see no behavior differences between your (1) and (2) calls.

There would only ever be a difference if one or the other constructors didn't exist (in which case one or the other wouldn't compile), or if they did different things.

Upvotes: 6

ravi
ravi

Reputation: 10733

Instead of taking a value_type emplace takes a variadic list of arguments, so that means that you can now perfectly forward the argument and construct directly an object into a container without temporary at all contrary to push which could involve temporaries.

Below is standard definition for emplace:-

Pushes new element on top of the stack. The element is constructed in-place, i.e. no copy or move operations are performed. The constructor of the element is called with exactly the same arguments as supplied to the function.

Upvotes: 0

Related Questions