Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[ #include <stack> ] What's the difference?

84 views
Skip to first unread message

SIMON

unread,
Jun 11, 2021, 1:58:16 PM6/11/21
to
Does anybody know the significant difference between:

> myStack.push(30);
>
> myStack.emplace(30);
>
It does the same thing as far as I can see but surely there must be
something that I don't know about these two methods.



SIMON

unread,
Jun 11, 2021, 2:10:14 PM6/11/21
to

Scott Lurndal

unread,
Jun 11, 2021, 2:21:23 PM6/11/21
to

Richard Damon

unread,
Jun 11, 2021, 2:29:19 PM6/11/21
to
It depends on the type that the stack is made from.

push() takes an object of that type, and copies it to the stack.
emplace() takes the arguments needed to construct an object of that type
an makes a new object from the arguments given.

For a type like int, there isn't a difference.

If it was a stack of so Point, with a contructor that two arguments it
would.

to push you would do something like:

myStack.push(Point(x, y));

or

Point point(x,y);
myStack.push(point);

while emplace would be

myStack.emplace(x,y);

Kli-Kla-Klawitter

unread,
Jun 11, 2021, 2:35:55 PM6/11/21
to
push and emplace are the same for stack - always!

Manfred

unread,
Jun 12, 2021, 2:07:12 PM6/12/21
to
push() takes a reference to an object that has already been constructed,
and pushes it on the stack. This operation involves a copy or move
operation.
emplace() constructs the object on the stack in-place, using the
arguments supplied. This can save a copy or move operation.
For 'int' there is no difference.

Scott gave you a good reference for the details.

Kli-Kla-Klawitter

unread,
Jun 12, 2021, 2:12:55 PM6/12/21
to
> For 'int' there is no difference.

The external storage of an int could be moved.

MrSpook_m...@o18rpnvgrx0dq.co.uk

unread,
Jun 13, 2021, 4:34:28 AM6/13/21
to
On Sat, 12 Jun 2021 20:06:53 +0200
Manfred <non...@add.invalid> wrote:
>On 6/11/2021 7:55 PM, SIMON wrote:
>> Does anybody know the significant difference between:
>>
>>> myStack.push(30);
>>>
>>> myStack.emplace(30);
>>>
>> It does the same thing as far as I can see but surely there must be
>> something that I don't know about these two methods.
>>
>>
>>
>
>push() takes a reference to an object that has already been constructed,

One would hope that a modern compiler would optimise out the temporary however
so there shouldn't actually be any difference between emplace() and push()
in practice.

Öö Tiib

unread,
Jun 13, 2021, 7:31:55 AM6/13/21
to
Take something bit less trivial than int (that is more common in practice):

struct WordCount {std::string word; size_t count;};

I do not think there is any compiler that compiles equal code to emplace("blah", 1)
and push(WordCount{"blah", 1}). Also I do not think there is way how conforming
compiler can do it even in theory.

By my understanding of standard the
* When copy (or move) constructors and destructors do not have side effects
(like it is with int) then those can be elided by as-if rule.
* Copy (or move) elision is allowed during initialization of object with temporary.
* It is mandatory since C++17 when temporary is used as return value (RVO).
* It is allowed when automatic, named, non-volatile, non-function-parameter,
non-catch-clause-parameter is used as return value (NRVO).
* Rest of cases allowed are about constexpr, throws, catches and coroutines.

Did I miss some? WordCount allocates and throws in constructor and is function
parameter of push() so as-if rule does not work nor none of other cases when
copy can be elided.

Andrey Tarasevich

unread,
Jun 23, 2021, 1:17:28 PM6/23/21
to
Without the exact type of 'myStack' the question is meaningless and does
not have an answer.

--
Best regards,
Andrey Tarasevich

James Kuyper

unread,
Jun 24, 2021, 5:23:43 PM6/24/21
to
What more do you need to know about the the type of myStack that you
don't already know?
The subject line says "#include <stack>", so you can reasonably presume
from its name that myStack is of type std::stack<T, Container> for some
values of T and Container. The differences between push() and emplace()
for that class template are specified precisely in the standard in 22.6.6.1:

template<class T, class Container = deque<T>>
class stack {
public:
using value_type = typename Container::value_type;

private:
Container c;
...
void push(const value_type& x)
{ c.push_back(x); }
void push(value_type&& x)
{ c.push_back(std::move(x)); }
template<class... Args>
decltype(auto) emplace(Args&&... args)
{ return c.emplace_back(std::forward<Args>(args)...); }

Andrey Tarasevich

unread,
Jul 6, 2021, 3:50:42 PM7/6/21
to
On 6/24/2021 2:23 PM, James Kuyper wrote:
> On 6/23/21 1:17 PM, Andrey Tarasevich wrote:
>> On 6/11/2021 10:55 AM, SIMON wrote:
>>> Does anybody know the significant difference between:
>>>
>>>> myStack.push(30);
>>>>
>>>> myStack.emplace(30);
>>>>
>>> It does the same thing as far as I can see but surely there must be
>>> something that I don't know about these two methods.
>>
>> Without the exact type of 'myStack' the question is meaningless and does
>> not have an answer.
>
> What more do you need to know about the the type of myStack that you
> don't already know?
> The subject line says "#include <stack>", so you can reasonably presume
> from its name that myStack is of type std::stack<T, Container> for some
> values of T and Container.

I need to know what `T` is. I need to know whether `myStack` holds
`int`s, or `myStack` holds something else, perhaps some non-trivial,
unrelated, possibly "heavy" type, which just happens to be implicitly
convertible from `int`.

For `T == int` the difference between the variants would be purely
conceptual, without any practical consequences.

For a "heavy" `T` the difference between these two variants can be
substantial. `push` would construct a temporary followed by two moves
from it into a new container entry, while `emplace` would construct a
new container entry in-place from the twice-forwarded `30`.

James Kuyper

unread,
Jul 6, 2021, 9:17:53 PM7/6/21
to
That doesn't make the question "meaningless", nor does it prevent the
question from having an answer. The question can be answered in full by
quoting what the standard says about std::stack<T, Container>::push()
and emplace(). The ways in which the behavior depends upon T and
Containter are completely determined by what the standard says about
those functions, directly or indirectly. The "significant difference"
between those two functions that the OP was talking about consists
entirely of the differences between what the standard says about them,
along with the T-dependent implications of those differences.

Andrey Tarasevich

unread,
Jul 7, 2021, 12:59:24 AM7/7/21
to
On 7/6/2021 6:17 PM, James Kuyper wrote:
> On 7/6/21 3:50 PM, Andrey Tarasevich wrote:
>> On 6/24/2021 2:23 PM, James Kuyper wrote:
>>> ...
>>> What more do you need to know about the the type of myStack that you
>>> don't already know?
>>> The subject line says "#include <stack>", so you can reasonably presume
>>> from its name that myStack is of type std::stack<T, Container> for some
>>> values of T and Container.
>>
>> I need to know what `T` is. I need to know whether `myStack` holds
>> `int`s, or `myStack` holds something else, perhaps some non-trivial,
>> unrelated, possibly "heavy" type, which just happens to be implicitly
>> convertible from `int`.
>>
>> For `T == int` the difference between the variants would be purely
>> conceptual, without any practical consequences.
>>
>> For a "heavy" `T` the difference between these two variants can be
>> substantial. `push` would construct a temporary followed by two moves
>> from it into a new container entry, while `emplace` would construct a
>> new container entry in-place from the twice-forwarded `30`.
>
> That doesn't make the question "meaningless", nor does it prevent the
> question from having an answer. The question can be answered in full by
> quoting what the standard says about std::stack<T, Container>::push()
> and emplace(). The ways in which the behavior depends upon T and
> Containter are completely determined by what the standard says about
> those functions, directly or indirectly. The "significant difference"
> between those two functions that the OP was talking about consists
> entirely of the differences between what the standard says about them,
> along with the T-dependent implications of those differences.

This is just another way of saying that every C++ question can be
answered by a copy-paste of a link to the language standard. True, but
not very useful. Linking to a specific section does not change much from
qualitative point of view.

I'm confident that the OP meant to ask a very specific question and
expected to receive a very specific answer. Namely, the OP probably
assumed that we'll immediately "deduce" `myStack` as `std::stack<int>`.
I'm just pointing out the fact that this is an unjustified assumption.
When asking questions, don't assume. Strive to provide all relevant
information.

Yes, sometimes it is difficult to properly include every important
detail at the first try. But what we got here is ridiculously insufficient.
0 new messages