尝试了解push()
使用emplace()
或std::stack
之间的区别。
我在想如果我创建一个std::stack<int>
,那么我就会使用push()
,因为整数是一种原始类型,emplace()
无需构建。
但是,如果我正在创建std::stack<string>
,那么我选择emplace()
,因为std::string
是一个对象。
这是正确的用法吗?
答案 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))
首先创建一个临时的,然后移动到矢量中。