C ++:Stack push()vs emplace()

时间:2014-10-05 00:03:06

标签: c++ stack

尝试了解push()使用emplace()std::stack之间的区别。

我在想如果我创建一个std::stack<int>,那么我就会使用push(),因为整数是一种原始类型,emplace()无需构建。

但是,如果我正在创建std::stack<string>,那么我选择emplace(),因为std::string是一个对象。

这是正确的用法吗?

2 个答案:

答案 0 :(得分:36)

要完全理解emplace_back的作用,首先必须了解可变参数模板和右值引用。

这是现代C ++中相当先进,深刻的概念。在地图上,它会被标记为“有龙”。

你说你是C ++的新手并试图学习这些东西。这可能不是您可能正在寻找的答案,但您现在应该跳过这个细节,并在您将大脑包裹在可变参数模板和右值参考之后再回来。那么它应该都有意义。

但是如果你坚持:对于一个包含简单的基本类型(如整数)的容器,几乎没有什么区别。当容器的类型是一些大型的复杂类,具有复杂的构造函数和/或复制构造函数时,就会出现差异。

push或emplace的最终结果恰好是100%,相同。容器会附加另一个元素。不同之处在于元素的来源:

1)push获取现有元素,并将其副本附加到容器中。简单,直截了当。 push总是只接受一个参数,即复制到容器的元素。

2)emplace在容器中创建另一个类实例,该实例已经附加到容器中。 emplace的参数作为参数转发给容器的类的构造函数。如果类具有默认构造函数,则Emplace可以有一个参数,多个参数或根本没有参数。

请注意,当类的构造函数接受一个参数并且未标记为explicit时,可能会滥用push并将其传递给构造函数参数,而不是该类的现有实例。但是让我们假装这个选项不存在,它经常导致可怕的代码性能,特别是对于非平凡的类。

所以:如果要将类的现有实例的副本添加到容器中,请使用push。如果要从头开始创建类的新实例,请使用emplace。

答案 1 :(得分:11)

如果您有vector<X>,那么emplace_back(a, b, c)会构建向量中的X对象。

相比之下,push_back(X(a, b, c))首先创建一个临时的,然后移动到矢量中。