push_back vs emplace_back
我对push_back
和emplace_back
之间的区别有些困惑。
void emplace_back(Type&& _Val);
void push_back(const Type& _Val);
void push_back(Type&& _Val);
由于有一个push_back
超载进行RVALUE参考,因此我不太了解emplace_back
的目的是什么?
I'm a bit confused regarding the difference between push_back
and emplace_back
.
void emplace_back(Type&& _Val);
void push_back(const Type& _Val);
void push_back(Type&& _Val);
As there is a push_back
overload taking a rvalue reference I don't quite see what the purpose of emplace_back
becomes?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
除了访客所说的内容外,
MSCV10提供的函数
void emplace_back(type& amp; amp; _val)
是不合格和多余的,因为正如您所指出的那样,它严格等同于push_back_back(type& amp; amp; & _val)
。但是
emplace_back
的真实C ++ 0x形式确实有用:void emplace_back(args&& ...)
;它没有采用
value_type
,而是获取参数的变化列表,因此这意味着您现在可以完美地转发参数并直接将对象直接构造到一个没有临时的容器中。这很有用,因为不管RVO和移动语义带来了多少聪明,仍然存在复杂的情况,
push_back
可能会制作不必要的副本(或移动)。例如,使用传统insert()
std :: map
的功能,您必须创建一个临时性,然后将其复制到std: :pair< key,value>
,然后将其复制到地图中:那么为什么他们不在MSVC中实现
emplace_back
的正确版本?实际上,它也使我烦恼了,所以我在 Visual C ++博客。这是Microsoft Visual C ++标准库实施的官方维护者Stephan T Lavavej的答案。这是一个可以理解的决定。每个尝试使用预处理程序可怕技巧模拟variadic模板的人都知道这些东西有多令人作呕。
In addition to what visitor said :
The function
void emplace_back(Type&& _Val)
provided by MSCV10 is non-conforming and redundant because as you noted it is strictly equivalent topush_back(Type&& _Val)
.But the real C++0x form of
emplace_back
is really useful:void emplace_back(Args&&...)
;Instead of taking a
value_type
, it takes a variadic list of arguments, so that means that you can now perfectly forward the arguments and construct directly an object into a container without a temporary at all.That's useful because no matter how much cleverness RVO and move semantics bring to the table, there are still complicated cases where a
push_back
is likely to make unnecessary copies (or move). For example, with the traditionalinsert()
function of astd::map
, you have to create a temporary, which will then be copied into astd::pair<Key, Value>
, which will then be copied into the map :So why didn't they implement the right version of
emplace_back
in MSVC? Actually, it bugged me too a while ago, so I asked the same question on the Visual C++ blog. Here is the answer from Stephan T Lavavej, the official maintainer of the Visual C++ standard library implementation at Microsoft.It's an understandable decision. Everyone who tried just once to emulate variadic template with preprocessor horrible tricks knows how disgusting this stuff gets.
emplace_back
不应采用类型vector :: value_type
的参数,而应转发给附录项目的构造函数。可以传递
value_type
将转发给复制构造函数。因为它可以转发参数,所以这意味着,如果您没有rvalue,这仍然意味着容器将存储“复制”副本,而不是移动的副本。
但是以上应该与
push_back
做什么相同。它可能是针对以下用例以下用例emplace_back
shouldn't take an argument of typevector::value_type
, but instead variadic arguments that are forwarded to the constructor of the appended item.It is possible to pass a
value_type
which will be forwarded to the copy constructor.Because it forwards the arguments, this means that if you don't have rvalue, this still means that the container will store a "copied" copy, not a moved copy.
But the above should be identical to what
push_back
does. It is probably rather meant for use cases like:emplace_back
的优化可以在以下示例中进行演示。对于
emplace_back
,将调用constructora(int x_arg)
。对于
push_back
,a(int x_arg)
被称为move a(a&amp;&amp; rhs)
后来调用。当然,必须将构造函数标记为
显式
,但是对于当前示例,可以删除显式。输出:
Optimization for
emplace_back
can be demonstrated in following example.For
emplace_back
, constructorA (int x_arg)
will be called.For
push_back
,A (int x_arg)
is called first andmove A (A &&rhs)
is called afterward.Of course, the constructor has to be marked as
explicit
, but for the current example, it is good to remove explicitness.output:
emplace_back
的特定用例:如果您需要创建一个临时对象,然后将其推入容器中,请使用emplace_back
而不是push_back
。它将在容器内创建对象。注意:
push_back
在上述情况下将创建一个临时对象并移动它进入容器。但是,用于
emplace_back
的现场构造将更多性能比构造然后移动对象(通常涉及一些复制)。
emplace_back
而不是push_back
而没有太多问题。 (请参阅例外)Specific use case for
emplace_back
: If you need to create a temporary object which will then be pushed into a container, useemplace_back
instead ofpush_back
. It will create the object in-place within the container.Notes:
push_back
in the above case will create a temporary object and move itinto the container. However, in-place construction used for
emplace_back
would be moreperformant than constructing and then moving the object (which generally involves some copying).
emplace_back
instead ofpush_back
in all the cases without much issue. (See exceptions)列表的另一个示例:
One more example for lists:
此处显示了推送_back和emplace_back的一个不错的代码。
http://en.cppreference.com/w/cpp/container/container/container/vector/vector/emplace/emplace/place_back
您可以在push_back上而不是emplace_back上看到移动操作。
A nice code for the push_back and emplace_back is shown here.
http://en.cppreference.com/w/cpp/container/vector/emplace_back
You can see the move operation on push_back and not on emplace_back.
emplace_back
符合实现将将参数转发到vector&lt; object&gt; :: value_type
constructor时添加到向量时。我记得Visual Studio不支持Variadic模板,但是在Visual Studio 2013 RC中将支持Variadic模板,因此我想将添加一个符合符号的签名。使用
emplace_back
,如果您将参数直接转发到vector&lt; object&gt; :: value_type
constructor,则不需要类型可移动或可复制的emplace_back
功能,严格来说。在vector&lt; noncopyablenonMovableObject&gt;
案例中,这无用,因为vector&lt; object&gt; :: value_type
需要可复制或可移动的类型才能成长。但是 Note 这对于
std :: map&lt; key,noncopyablenonMovableObject&gt;
,因为一旦您分配了地图中的条目,就无需移动它,因此与vector
不同,或者再复制了,这意味着您可以使用既无法复制也不可移动的映射类型有效地使用std :: map
。emplace_back
conforming implementation will forward arguments to thevector<Object>::value_type
constructor when added to the vector. I recall Visual Studio didn't support variadic templates, but with variadic templates will be supported in Visual Studio 2013 RC, so I guess a conforming signature will be added.With
emplace_back
, if you forward the arguments directly tovector<Object>::value_type
constructor, you don't need a type to be movable or copyable foremplace_back
function, strictly speaking. In thevector<NonCopyableNonMovableObject>
case, this is not useful, sincevector<Object>::value_type
needs a copyable or movable type to grow.But note that this could be useful for
std::map<Key, NonCopyableNonMovableObject>
, since once you allocate an entry in the map, it doesn't need to be moved or copied ever anymore, unlike withvector
, meaning that you can usestd::map
effectively with a mapped type that is neither copyable nor movable.emplace_back 函数是 std :: vector 容器的方法。它直接将新元素(例如,一个std ::螺纹对象)构造和附加到向量。
例如:
The emplace_back function is a method of the std::vector container. It constructs and appends a new element (e.g., a std::thread object) directly to the vector.
For example: