为什么没有vector::push_back
采用转发引用而不是两次重载?我已经读过你想要在左值和左值上重载的唯一原因是你的函数对它们做了不同的处理,那么vector::push_back
的两个重载除了移动/复制之外还有什么不同?
答案 0 :(得分:50)
我这样做主要是因为情况的演变。在C ++ 11之前,只有:
vector<T>::push_back(const T&);
随着rvalue引用的引入我推荐了 add 的重载:
vector<T>::push_back(T&&);
而不是将原始签名更改为:
template <class U> vector<T>::push_back(U&&);
这个决定的一部分是因为对后向兼容性的担忧(无论是否保证),以及缓解供应商和委员会其他人对这是一个简单的添加功能的担忧,而不是对现有功能的更改。
如果我今天从头开始重新设计vector
,我会认真考虑:
template <class U> vector<T>::push_back(U&&);
或者只是:
template <class ...Args> vector<T>::emplace_back(Args&& ...);
您可能想知道的详细信息位于N1858。
为什么不push_back
按值?
此问题已被标记为重复:
Why do C++11 std containers have pass-by-ref and pass-by-rvalue insert/push methods?
提出这个问题。所以我认为在这个答案中真正解决这个方面是礼貌的事情......
对于左值和小值,与副参考解决方案相比,push_back(T)
将花费额外的移动结构。 xvalues需要2个移动结构,左值需要1个复制结构和1个移动结构。
相比之下,在目前的设计中,左值成本为1个复制结构,x值为1个移动构造。
对于某些类型T
,移动构造并不便宜。 vector<T>
假设T
总是便宜地移动,这将是一个糟糕的设计选择。例如,如果T
是std::array<double, 100>
,该怎么办?更改为按值设计需要2个复制结构,而不是1到push_back
(prvalues除外)。
按价值解决方案确实具有优势,并且应该使用它的时间。只是vector<T>::push_back()
不是那个时代之一。