通过保留和复制复制向量,还是通过创建和交换复制向量更有效?

我试图有效地复制一个矢量,我看到了两种可能的方法:

std::vector<int> copyVecFast1(const std::vector<int>& original)
{
std::vector<int> newVec;
newVec.reserve(original.size());
std::copy(original.begin(), original.end(), std::back_inserter(newVec));
return newVec;
}


std::vector<int> copyVecFast2(std::vector<int>& original)
{
std::vector<int> newVec;
newVec.swap(original);
return newVec;
}

这些是首选的,为什么? 我正在寻找最有效的解决方案,将避免不必要的复制。

421680 次浏览

但它们是不一样的,对吗? 一个是拷贝,另一个是交换。因此函数名。

我最喜欢的是:

a = b;

其中 ab是向量。

你不应该使用交换来复制向量,它会改变“原始”向量。

将原始数据作为参数传递给 new。

这是另一种复制向量的有效方法,只需使用它的构造函数:

std::vector<int> newvector(oldvector);

这甚至比使用 std::copy将整个矢量从头到尾遍历到 std::back_insert使它们进入新矢量更简单。

也就是说,您的 .swap()1不是一个副本,而是交换两个向量。你会修改原件,不再包含任何东西!这不是复制品。

你的第二个例子不工作,如果你发送参数的引用。你的意思是

void copyVecFast(vec<int> original) // no reference
{


vector<int> new_;
new_.swap(original);
}

那样可以,但更简单的办法是

vector<int> new_(original);
new_vector.assign(old_vector.begin(),old_vector.end()); // Method 1
new_vector = old_vector; // Method 2

直接回答:

  • 使用 =操作员

我们可以使用容器 std::vector的公共成员函数 std::vector::operator=将值从一个向量分配给另一个向量。

  • 使用构造函数

此外,构造函数也是有意义的。使用另一个向量作为参数的构造函数(例如 x)按照相同的顺序构造一个包含 x中每个元素的副本的容器。

注意:

  • 不要使用 std::vector::swap

std::vector::swap不是 < em > 复制 一个向量到另一个,它实际上是交换两个向量的元素,正如它的名字所暗示的那样。换句话说,要从中复制的源向量在调用 std::vector::swap之后被修改,这可能不是您所期望的。

  • 深拷贝还是浅拷贝?

如果源向量中的元素是指向其他数据的指针,那么有时需要一个深度副本。

根据维基百科:

深度副本,意味着字段被解引用: 不是对被复制的对象的引用,而是为任何被引用的对象创建新的副本对象,并将对这些对象的引用放在 B 中。

实际上,目前在 C + + 中还没有一种内置的方法来进行深度复制。上面提到的所有方法都是肤浅的。如果需要深度复制,可以遍历向量并手动复制引用。或者,可以考虑使用迭代器进行遍历。关于迭代器的讨论超出了这个问题的范围。

参考文献

Cplusplus.com 上的 std::vector页面