C++:堆栈的 push() 与 emplace()
试图了解 std::stack
使用 push()
或 emplace()
之间的区别.
Trying to understand the difference between using push()
or emplace()
for std::stack
.
我在想,如果我创建一个 std::stack<int>
,那么我会使用 push()
因为整数是原始类型并且有emplace()
没有什么可构造的.
I was thinking that if I create a std::stack<int>
, then I'd use push()
because integer is a primitive type and there is nothing for emplace()
to construct.
但是,如果我正在创建 std::stack<string>
那么我会选择 emplace()
因为 std::string
是一个对象.
However, if I was creating std::stack<string>
then I'd choose emplace()
because std::string
is an object.
这是正确的用法吗?
推荐答案
要完全理解 emplace_back 的作用,首先必须了解可变参数模板和右值引用.
To fully understand what emplace_back does, one must first understand variadic templates and rvalue references.
这是现代 C++ 中一个相当先进和深刻的概念.在地图上,它会被标记为有龙".
This is a fairly advanced, and deep concept in modern C++. On a map, it would be labeled "there be dragons".
你说你是 C++ 的新手,并试图学习这些东西.这可能不是您正在寻找的答案,但您现在应该跳过这个细节,等您将大脑包裹在可变参数模板和右值引用上之后再回来.那么这一切都应该是有意义的.
You say that you're new to C++ and trying to learn this stuff. This may not be the answer you might be looking for, but you should skip this detail for now, and come back later after you've wrapped your brain around variadic templates and rvalue references. Then it should all make sense.
但如果您坚持:对于包含简单的基本类型(如整数)的容器,几乎没有区别,如果有的话.当容器的类型是一些大型的、复杂的类,具有复杂的构造函数和/或复制构造函数时,差异就出现了.
But if you insist: for a container containing simple, elementary types like integers, there's little, if any difference. The difference comes when the container's type is some large, sophisticated class, with a complicated constructor, and/or copy-constructor.
push 或 emplace 的最终结果完全相同,100% 相同.容器获取附加到它的另一个元素.不同之处在于元素的来源:
The end result of either push or emplace is exactly, 100%, the same. The container gets another element appended to it. The difference is where the element comes from:
1) push 获取一个现有元素,并将其副本附加到容器中.简单,直接.push 总是只接受一个参数,即要复制到容器的元素.
1) push takes an existing element, and appends a copy of it to the container. Simple, straightforward. push always takes exactly one argument, the element to copy to the container.
2) emplace 在容器中创建该类的另一个实例,该实例已经附加到容器中.emplace 的参数作为参数转发给容器类的构造函数.如果类具有默认构造函数,Emplace 可以有一个参数、多个参数或根本没有参数.
2) emplace creates another instance of the class in the container, that's already appended to the container. The arguments to emplace are forwarded as arguments to the container's class's constructor. Emplace can have either one argument, more than one argument, or no argument at all, if the class has a default constructor.
请注意,当类的构造函数采用一个参数且未标记为 explicit
时,可能会滥用 push 并向其传递构造函数参数,而不是现有的类实例.但是让我们假设这个选项不存在,它通常会导致糟糕的代码性能,尤其是对于非平凡的类.
Note that when the class's constructor takes one argument and it is not marked as explicit
, it's possible to abuse push and pass it a constructor argument, instead of an existing instance of the class. But let's pretend that this option does not exist, it often leads to horrible code performance, especially with non-trivial classes.
所以:如果您想将现有类实例的副本添加到容器中,请使用 push.如果您想从头开始创建该类的新实例,请使用 emplace.
So: if you want to add a copy of an existing instance of the class to the container, use push. If you want to create a new instance of the class, from scratch, use emplace.
相关文章