C++ 在这种情况下,std::stack::push()和std::stack::emplace()之间有区别吗?

C++ 在这种情况下,std::stack::push()和std::stack::emplace()之间有区别吗?,c++,c++11,emplace,C++,C++11,Emplace,请看以下代码: 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

请看以下代码:

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)

但是我不知道我所描述的情况有什么不同,因为
push()
emplace()
都应该引用本地
虚拟对象,并使用copy-ctor或类似的方法创建一个新对象。
push()
是否在此过程中创建了任何临时对象?

而不是获取值\u type emplace获取可变参数列表,这意味着您现在可以完美地转发参数并直接将对象构造到容器中,而无需临时对象,而push可能涉及临时对象

以下是就业的标准定义:-


将新元素推到堆栈顶部。元素是就地构造的,即不执行复制或移动操作。调用元素的构造函数时使用的参数与提供给函数的参数完全相同。

将没有临时参数。对于标准,
push
看起来像:

void push(const value_type& x) { c.push_back(x); }
void push(value_type&& x) { c.push_back(std::move(x)); }
template <class... Args>
void emplace(Args&&... args) { 
    c.emplace_back(std::forward<Args>(args)...);
}
emplace
看起来像:

void push(const value_type& x) { c.push_back(x); }
void push(value_type&& x) { c.push_back(std::move(x)); }
template <class... Args>
void emplace(Args&&... args) { 
    c.emplace_back(std::forward<Args>(args)...);
}
模板
空侵位(Args&…Args){
c、 后置炮位(标准:前置炮位(args)…);
}
其中
c
是底层容器,默认为
deque
。因此,在前一种情况下,当您调用push时,您正在调用
push(constdummy&)
,它将通过
Dummy(constdummy&)
创建一个新对象。在后一种情况下,您正在调用
emplace\u back(Dummy&)
,它通过
Dummy(Dummy&)
直接创建一个新对象

在您的例子中,这两个副本构造函数之间没有区别。它们都将调用由编译器隐式创建的平凡副本构造函数。因此,您应该看不到
(1)
(2)
调用之间的行为差异


只有当一个或另一个构造函数不存在(在这种情况下,一个或另一个不会编译),或者如果它们做了不同的事情,才会有差异

你为什么认为需要有所不同?一般来说,emplace是push的替代品,更通用,有时更高效。它们都构造传入参数的副本,所以没有区别
emplace()
在您希望像以前那样完善前向参数时非常有用。由于您正在传递参数,第二个调用Dummy::Dummy(const Dummy&)不是很有用吗?我认为emplace有一个用途,比如s.emplace()@除了
s.emplace()
只会尝试默认构造
Dummy
。有一个隐式
Dummy(Dummy&)
构造函数?有一个隐式
Dummy(const Dummy&)
,它将使用非常量ref调用。