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?
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.