【问题标题】:Copying std::vector: prefer assignment or std::copy?复制 std::vector:更喜欢赋值还是 std::copy?
【发布时间】:2013-02-05 07:45:31
【问题描述】:

我有两个向量:

std::vector<int> v1, v2;

// Filling v1
...

现在我需要将v1 复制到v2。有什么理由更喜欢

v2 = v1;

std::copy (v1.begin(), v1.end(), v2.begin());

(反之亦然)?

【问题讨论】:

  • 赋值运算符会做正确的事。你写copy的方式,如果v1大于v2就会搞砸。
  • 如果复制后不需要v1,您可以只需要v2.swap(v1);
  • 写下你想做的事。如果您想将一个向量分配给另一个向量,请写下。

标签: c++ stl copy


【解决方案1】:

一般来说我更喜欢v2 = v1:

  1. 它更短,意图更清晰
  2. 如果v2 的长度与v1 的长度不同,std::copy 将不起作用(它不会调整它的大小,因此它会保留一些旧元素最好的情况(v2.size() &gt; v1.size() 并覆盖一些随机数据用于程序最坏情况的其他地方
  3. 如果v1 即将过期(并且您使用C++11),您可以轻松地将其修改为move 的内容
  4. 性能分配不太可能比std::copy 慢,因为实现者可能会在内部使用std::copy,如果它可以带来性能优势。

总之,std::copy 表达能力较差,可能会做错事,而且速度也不会更快。所以没有任何理由在这里使用它。

【讨论】:

  • 那么,std::copy 是干什么用的?
  • @altroware:用于从一个范围到另一个范围的一般复制。例如,您不能使用赋值运算符从std::list 复制到std::vector,或从std::vector 的一部分复制到同一std::vector 的另一部分。
  • 如果 v1 被分配到堆栈上并被破坏会发生什么? v2 = v1 是否会导致 v1 的元素被复制?
  • 元素类型的复制机制调用的是什么?在这种vector&lt;int&gt; 的情况下,整数是使用operator= 还是使用int 的复制构造函数从一个向量复制到另一个向量?
  • 在这种情况下,您将如何实现 operator=?
【解决方案2】:

如果v2 不够大,如果您照常使用copy,则会出现缓冲区溢出。

您可以使用后插入迭代器,它将在v2 上调用 push_back。但是,这可能会导致多次重新分配,具体取决于 v1 的大小。

copy(v1.begin(), v1.end(), back_inserter(v2));

您最好让vector 正确管理事情。赋值运算符会这样做,vector::assign 也是如此:

v2.assign(v1.begin(), v1.end());

我知道赋值运算符是根据vector::assign 实现的。

【讨论】:

  • 先生。伍德,你的意思是 v2.assign(v1.begin(), v1.end()) 而不是 v2.assign(v1.begin(), v2.end()) 吗?
【解决方案3】:

std::copy 的调用可能会尝试访问超出目标向量末尾的项目。

使用赋值。

微优化不是你的工作:这是库编写者的责任,最终也是编译器的责任。

你可以让你的代码任意快如果它不需要是正确的。

然而,在copy 的情况下,它是否更快是相当值得怀疑的,而且对于一般情况来说肯定是不正确的。

【讨论】:

  • 我同意你关于优化的说法,但可能值得指出的是,编译器或库可用的信息越多,它的工作就越好。 std::vector 的成员函数知道他们正在处理std::vector,并且知道它是如何实现的。 std::copy 没有此信息。结论是成员函数可能会做得更好(当然不会更差)。
【解决方案4】:

它更短。

std::copy 主要用于复制容器的各个部分。如果需要复制整个容器,不妨使用复制构造函数。

【讨论】:

  • 如果v2 不够大,你会遇到缓冲区溢出。
【解决方案5】:

任务,到目前为止。更一般地说,任何时候向量的大小可能会改变,或者改变向量的全部内容,你应该更喜欢成员函数。唯一适合 std::copy 的情况是,如果您只是完全替换向量内的一小部分范围。

【讨论】:

    【解决方案6】:

    分配更清晰,内部使用std::copy(或unitizalized_copy_M_allocate_and_copy,取决于大小和容量)左右性能相同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-30
      • 1970-01-01
      • 1970-01-01
      • 2012-11-25
      • 2012-03-07
      • 2020-08-06
      • 2012-09-04
      • 2015-04-01
      相关资源
      最近更新 更多