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

发布于 2024-07-14 14:13:23 字数 503 浏览 5 评论 0原文

我正在尝试有效地复制向量。 我看到两种可能的方法:

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;
}

首选哪种方法,为什么? 我正在寻找最有效的解决方案,以避免不必要的复制。

I am trying to efficiently make a copy of a vector. I see two possible approaches:

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;
}

Which of these is preferred, and why? I am looking for the most efficient solution that will avoid unnecessary copying.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

回眸一笑 2024-07-21 14:13:23

但它们并不相同,不是吗? 一个是副本,另一个是交换。 因此就有了函数名称。

我最喜欢的是:

a = b;

其中 ab 是向量。

They aren't the same though, are they? One is a copy, the other is a swap. Hence the function names.

My favourite is:

a = b;

Where a and b are vectors.

夜还是长夜 2024-07-21 14:13:23

如果您通过引用发送参数,您的第二个示例将不起作用。 你的意思是

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

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

那会起作用,但更简单的方法是

vector<int> new_(original);

Your second example does not work if you send the argument by reference. Did you mean

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

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

That would work, but an easier way is

vector<int> new_(original);
长不大的小祸害 2024-07-21 14:13:23

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

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

这比使用 std::copy 将整个向量从头到尾遍历到 std 还要简单: :back_insert 将它们插入到新向量中。

话虽如此,您的 .swap() 不是副本,而是交换两个向量。 您将修改原始内容以不再包含任何内容! 这不是副本。

This is another valid way to make a copy of a vector, just use its constructor:

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

This is even simpler than using std::copy to walk the entire vector from start to finish to std::back_insert them into the new vector.

That being said, your .swap() one is not a copy, instead it swaps the two vectors. You would modify the original to not contain anything anymore! Which is not a copy.

瀞厅☆埖开 2024-07-21 14:13:23

直接答案:

  • 使用=运算符

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

  • 使用构造函数

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

注意:

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

std::vector::swap 不是复制一个向量到另一个向量,顾名思义,它实际上是交换两个向量的元素。 换句话说,要复制的源向量在调用 std::vector::swap 后被修改,这可能不是您所期望的。

  • 深拷贝还是浅拷贝?

如果源向量中的元素是指向其他数据的指针,则有时需要深层复制。

根据维基百科:

深层复制,意味着字段被取消引用:不是对正在复制的对象的引用,而是为任何引用的对象创建新的复制对象,并对这些对象的引用放置在 B 中。

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

参考文献

cplusplus.com 上的std::vector页面

Direct answer:

  • Use a = operator

We can use the public member function std::vector::operator= of the container std::vector for assigning values from a vector to another.

  • Use a constructor function

Besides, a constructor function also makes sense. A constructor function with another vector as parameter(e.g. x) constructs a container with a copy of each of the elements in x , in the same order.

Caution:

  • Do not use std::vector::swap

std::vector::swap is not copying a vector to another, it is actually swapping elements of two vectors, just as its name suggests. In other words, the source vector to copy from is modified after std::vector::swap is called, which is probably not what you are expected.

  • Deep or shallow copy?

If the elements in the source vector are pointers to other data, then a deep copy is wanted sometimes.

According to wikipedia:

A deep copy, meaning that fields are dereferenced: rather than references to objects being copied, new copy objects are created for any referenced objects, and references to these placed in B.

Actually, there is no currently a built-in way in C++ to do a deep copy. All of the ways mentioned above are shallow. If a deep copy is necessary, you can traverse a vector and make copy of the references manually. Alternatively, an iterator can be considered for traversing. Discussion on iterator is beyond this question.

References

The page of std::vector on cplusplus.com

旧城烟雨 2024-07-21 14:13:23
new_vector.assign(old_vector.begin(),old_vector.end()); // Method 1
new_vector = old_vector; // Method 2
new_vector.assign(old_vector.begin(),old_vector.end()); // Method 1
new_vector = old_vector; // Method 2
倦话 2024-07-21 14:13:23

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

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

you should not use swap to copy vectors, it would change the "original" vector.

pass the original as a parameter to the new instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文