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

Jos*_*ant 24 c++ stack

试图理解使用push()emplace()for 之间的区别std::stack.

我在想,如果我创建一个std::stack<int>,那么我会使用push()因为整数是一种原始类型而且没有任何东西emplace()需要构造.

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

这是正确的用法吗?

Sam*_*hik 45

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

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

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

但是如果你坚持认为:对于一个包含简单的基本类型(如整数)的容器,如果有任何差异,那就很少了.当容器的类型是一些大型的复杂类,具有复杂的构造函数和/或复制构造函数时,就会出现差异.

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

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

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

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

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

  • 我想我明白什么时候我会使用进驻而不是推动。我肯定会查找有关可变参数模板和右值引用的信息。 (2认同)
  • @antred - push_back() 允许统一的初始化语法。emplace_back(),因为它是一个模板函数,所以没有。 (2认同)

fre*_*low 12

如果你有一个vector<X>,那么在向量中emplace_back(a, b, c)构造X对象.

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

  • 这将创建临时 X(a,b,c),并尝试在向量内构造 X,以临时值作为参数,这应该使用移动构造函数。一般来说,如果您想知道 emplace 会发生什么,问问自己“如果我用对象名称替换 emplace_back 会发生什么”?它基本上就是这样做的——除了它使用的内存正是向量想要的位置,因此避免了额外的移动/复制步骤push_back需要做的事情。 (3认同)
  • 那么,'emplace_back(X(a,b,c))`怎么样? (2认同)