为什么有两个重载的vector :: push_back? [英] Why are there two overloads for vector::push_back?

查看:885
本文介绍了为什么有两个重载的vector :: push_back?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么 vector :: push_back 采用转发引用,而不是有两个重载?我读过,你想要重载的左值和右值是唯一的原因是,如果你的函数做不同的东西,他们,所以如何两个重载 vector :: push_back 不同于移动/复制?

解决方案

我这样做主要是因为情况的演变。在C ++ 11之前,只有:

 向量< T> :: push_back(const T& 

引入右值引用后,我推荐重载的添加

 矢量< T> :: push_back(T&& 

而不是将原始签名更改为:

  template< class U> vector< T> :: push_back(U&&&&& 

这个决定的一部分是由于一些关于向后兼容性(无论是否保证)以减轻供应商和其他委员会对这是简单的添加功能的关注,而不是对现有功能的更改。



如果我今天从头开始重新设计向量,我会认真考虑:

  template< class U> vector< T> :: push_back(U&&&&& 

或者只是:

  template< class ... Args> vector< T> :: emplace_back(Args& ...); 

您可能想知道的细节在 N1858



为什么不按 push_back 按价值



问题已标记为重复的:



为什么C ++ 11 std container有pass-by-ref和pass-by-rvalue插入/ push方法?



这个问题。所以我想在这个答案中实际解决这个方面是有礼貌的事情...



对于左值和x值,一个 push_back (T)与参考解决方案相比会花费额外的移动。 xvalues将需要2个移动构造,并且lvalue将需要1个拷贝构造和1个移动构造。相反,对于当前设计,l​​values成本1拷贝构造和xvalues成本1移动施工。



对于一些类型 T ,移动施工不便宜。对于向量< T> 假定 T 总是便宜可移动,这将是一个差的设计选择。例如,如果 T std :: array< double,100> 更改为按值设计将需要2个副本构造,而不是1到 push_back (除了prvalues)。



按值解决方案确实有优势,并且应该使用它的次数。只是向量< T> :: push_back()不是这些时间之一。


Why doesn't vector::push_back take a forwarding reference instead of having two overloads? I've read that the only reason you'd want to overload on lvalues and rvalues is if your functions do something differently for them, so how do both overloads of vector::push_back differ other than moving/copying?

解决方案

I did this largely just because of how the situation evolved. Prior to C++11, there was only:

vector<T>::push_back(const T&);

With the introduction of rvalue references I recommended the addition of the overload:

vector<T>::push_back(T&&);

instead of changing the original signature to:

template <class U> vector<T>::push_back(U&&);

Part of this decision was made because of some concerns about backward compatibility (whether warranted or not), and to ease concerns of both vendors and others on the committee that this was a simple addition of functionality, and not a change to existing functionality.

If I were redesigning vector from scratch today, I would seriously consider just having:

template <class U> vector<T>::push_back(U&&);

or perhaps just:

template <class ...Args> vector<T>::emplace_back(Args&& ...);

More details than you probably want to know about are in N1858.

Why not push_back by value?

This question has been marked as a duplicate of:

Why do C++11 std containers have pass-by-ref and pass-by-rvalue insert/push methods?

which asks this question. So I figured it would be the polite thing to do to actually address that aspect in this answer...

For lvalues and xvalues, a push_back(T) would cost an extra move construction compared to the by-reference solutions. xvalues would require 2 move constructions and lvalues would require 1 copy construction and 1 move construction.

In contrast, with the current design, lvalues cost 1 copy construction and xvalues cost 1 move construction.

For some types T, move construction is not cheap. It would be a poor design choice for vector<T> to assume that T is always cheaply movable. For example what if T is std::array<double, 100>? Changing to the by-value design would require 2 copy constructions instead of 1 to push_back (except for prvalues).

The by-value solution does have advantages, and times when it should be used. It is just that vector<T>::push_back() is not one of those times.

这篇关于为什么有两个重载的vector :: push_back?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆