复制原始类型行为的std :: vector

时间:2016-03-25 13:50:09

标签: c++ c++11 vector language-lawyer memcpy

背景

使用其复制构造函数复制std::vector或复制分配如下:

std::vector<T> v1{T(),T(),T()};
std::vector<T> v2 = v1;

发生深层复制。

标准是否保证会为每个元素触发T的复制构造函数?换句话说,不会调用memcpy(或类似的东西)。 (如果我错了,请纠正我。)

问题:

另一方面,标准是否保证它会在原始类型上调用memcpy(或类似的东西)(针对性能问题)?

2 个答案:

答案 0 :(得分:3)

是的,必须调用T的复制构造函数。如果复制构造函数是微不足道的,那么它的效果与memcpy的效果完全相同,因此使用后者来实现实现复制构造函数是很好的。从那时起,实现可能决定使用memcpy来实现vector的复制构造函数。该决定使用as-if rule:程序的可观察行为保持不变,因此我们不需要实际执行所有复制构造函数调用。

  

另一方面,它是否符合标准   在原始类型上调用memcpy(或类似的东西)(for   表现问题)?

不,因为实际实现了复制构造函数是一个实现细节。标准只是指定程序的(可观察的)行为,它使用复制构造函数等的概念来实现。优化不是抽象的标准文档应该担心的,而是您的供应商。实际上,限制这些函数的定义会导致优化中的巨大缺陷,或者由于前面提到的as-if规则而被完全忽略。

答案 1 :(得分:2)

为原始类型的复制构造生成的确切代码是实现质量问题。换句话说,标准不会保证任何类型的东西 - 充其量,它将指定操作的算法复杂性,在这种情况下,矢量的复制可以推断为O(n)

使用现代C ++编译器进行合理的优化设置,您可以依赖于在线实现的POD类的复制构造,与常量memcpy一样高效。做其他任何事情都会对典型的用例造成严重的惩罚,例如指针的STL容器。