为什么 vector::push_back 有两个重载?

Why are there two overloads for vector::push_back?

为什么 vector::push_back 不使用转发引用而不是使用两个重载?我读过你想要重载左值和右值的唯一原因是如果你的函数对它们做了不同的事情,那么 vector::push_back 的两个重载除了 moving/copying 之外有何不同?

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

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

随着右值引用的引入,我推荐了重载的添加

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?

哪个问这个问题。所以我认为在这个答案中实际解决这个方面是礼貌的做法......

对于左值和 x 值,与引用解决方案相比,push_back(T) 将花费额外的移动构造。 xvalues 需要 2 个 move 构造,lvalues 需要 1 个复制构造和 1 个 move 构造。

相比之下,在当前设计中,左值需要 1 个复制构造,而 xvalue 需要 1 个移动构造。

对于某些类型 T,移动构造并不便宜。对于 vector<T> 来说,假设 T 总是可以廉价移动是一个糟糕的设计选择。例如,如果 Tstd::array<double, 100> 怎么办?更改为按值设计将需要 2 个复制结构,而不是 1 个到 push_back(prvalues 除外)。

按值解决方案确实有其优点,以及应该使用它的时间。只是 vector<T>::push_back() 不是那个时代之一。