C ++ 11矢量构造函数复制与范围?

C++11 vector constructor copy vs range?

我无法理解向量复制构造函数和范围构造函数的优点或区别。当我像这样构建三个向量时:

    vector<int> FirstVec(3, 911); //fill constructor
    vector<int> SecondVec(FirstVec.begin(), FirstVec.end()); //range constructor
    vector<int> ThirdVec(FirstVec); //copy constructor

SecondVecThirdVec的内容完全一样。在任何情况下使用其中之一有优势吗?谢谢。

我相信分配器在一种情况下被复制,但在另一种情况下没有。

一般来说,如果你想复制一个向量,那么你应该复制这个向量。

当你想复制不同类型容器的项目,或者不想复制整个范围时,范围构造器非常有用。例如

int a[] = {1,2,3,4,5};
std::set<int> s{3, 911};
std::vector<int> v0{1,2,3,4,5};

std::vector<int> v1(std::begin(a), std::end(a));
std::vector<int> v2(a+1, a+3);
std::vector<int> v3(s.begin(), s.end());
vector<int> v4(v0.begin(), v0.begin() + 3);

范围构造函数更通用;您可以提供任何有效的合适元素序列,不一定来自同一类型的容器,或跨越整个容器,甚至根本不来自一个容器。

复制构造函数更简单并且可能更高效;但仅当您想要复制整个另一个矢量时才适用。

所以当你想复制同一种容器时,使用复制构造函数,就像你在这里所做的那样;以及更一般范围的范围构造函数。

如果您关心最后一个 CPU 周期和代码字节,除了上述答案之外,还有另一个重要的考虑因素。

当您使用复制构造函数时,它为库方法提供了充分的自由来处理完整的源向量。

使用范围说明符,该方法必须执行更多检查并变得通用化。正如您可以轻松想象的那样,范围的末尾可能与源向量的末尾不同。

假设我们正在开发库代码,看看有什么区别:

  • 目的地。矢量和 src。矢量将具有相同的大小。
  • 目的地。向量存储分配只是针对 _src.size.
    • 对于范围复制,就是end-begin+1。
  • 实际的数据复制也更简单:
    • 例如想象一个从源到目标的基于循环的元素副本。
    • 你从 source 的第一个元素开始复制所有内容。
    • 复制循环在源向量的末尾终止,而不是 range.end。

编译器编写者可能会提出更多要点。