C ++ STL Vector:Push_back参考

时间:2012-08-01 15:24:48

标签: c++ stl

std::vector的cpp文档中,我看到了:

void push_back ( const T& x );

我知道push_back会复制我传递的对象。但是,为什么签名const T& ?通过查看此内容,我最初认为它需要const引用我推送到vector的任何对象。

3 个答案:

答案 0 :(得分:12)

另一种选择是

void push_back(T x);

即按值x。但是,这将(在C ++ 03中)导致创建x的额外副本(push_back的参数中的副本)。通过const引用取x可以避免这种情况。

让我们看看按值获取的电话v.push_back(T())的堆栈:

v.push_back(T());                      // instance of T
void std::vector<T>::push_back(T x)    // copy of T
new (data_[size_ - 1]) T(x)            // copy of copy of T

通过const引用我们得到:

v.push_back(T());                             // instance of T
void std::vector<T>::push_back(const T &x)    // const reference to T
new (data_[size_ - 1]) T(x)                   // copy of T

在C ++ 11中,有可能(尽管没有必要)按值x并使用std::move将其移动到向量上:

v.push_back(T());                             // instance of T
void std::vector<T>::push_back(T x)           // copy of T
new (data_[size_ - 1]) T(std::move(x))        // move the copy of T

答案 1 :(得分:8)

只是为了澄清“额外副本”@ecatmur所描述的,如果push_back按值接收了它的参数,那么你将从你的对象开始。该副本将作为参数传递给push_back。然后push_back会创建的副本以放入矢量本身。

由于push_back的实际实现通过引用接收其参数,因此它(push_back)直接在向量中创建新对象作为原始对象的副本。

如前所述,是的,使用移动语义的C ++ 11,有可能(尽管可能不是特别有利)通过值传递参数,然后将该参数中的值移动到新的对象中向量。例如,如果你在向量中放置的是一个主要只包含一个指针和一些“簿记”字段(分配的内存量,当前使用的内存量)的字符串,那将是 与传递引用一样高效,因为移动只能执行浅拷贝 - 复制指针和簿记值本身,而不是它指向的所有数据。但是,如果有问题的对象直接保存了所有数据(即不是指针),那么移动就像复制一样慢。

通过引用传递,避免所有复制,因此即使像字符串这样的东西,它通常也更快(对于这样的情况,原始对象不能被无效)。它还具有使用C ++ 98/03的次要优势,而不仅仅是C ++ 11。

答案 2 :(得分:7)

您推送的object通过引用传递以避免extra copy。副本放在vector