c++ - vector 分配是否会使 `reserve` 无效?

标签 c++ language-lawyer

假设我写

std::vector<T> littleVector(1);
std::vector<T> bigVector;

bigVector.reserve(100);
bigVector = littleVector;

标准是否规定 bigVector 仍将保留 100 个元素?或者如果我要 push_back 99 个元素,我会经历内存重新分配吗?也许它甚至因 STL 实现而异。

这是之前讨论过的 here但没有给出标准引用。

最佳答案

不幸的是,该标准没有详细说明分配器感知序列容器分配的行为,严格来说确实是不一致的。

我们知道(从表 28 和 23.2.1p7)如果 allocator_traits<allocator_type>::propagate_on_container_copy_assignment::valuetrue然后分配器在复制分配时被替换。此外,从表 96 和 99 中我们发现,复制分配的复杂性线性,而操作a = t后置条件a == t ,即(表 96)distance(a.begin(), a.end()) == distance(t.begin(), t.end()) && equal(a.begin(), a.end(), t.begin()) .从 23.2.1p7 开始,复制分配后,如果分配器传播,则 a.get_allocator() == t.get_allocator() .

关于 vector 容量,23.3.6.3 [vector.capacity]有:

5 - Remarks: Reallocation invalidates all the references, pointers, and iterators referring to the elements in the sequence. It is guaranteed that no reallocation takes place during insertions that happen after a call to reserve() until the time when an insertion would make the size of the vector greater than the value of capacity().

如果我们采取library DR341作为阅读标准的指南:

However, the wording of 23.3.6.3 [vector.capacity]paragraph 5 prevents the capacity of a vector being reduced, following a call to reserve(). This invalidates the idiom, as swap() is thus prevented from reducing the capacity. [...]

通过在 23.3.6.3 中添加段落解决了 DR341:

void swap(vector<T,Allocator>& x);
7 - Effects: Exchanges the contents and capacity() of *this with that of x.
8 - Complexity: Constant time.

结论是,从图书馆委员会的角度来看,运营只修改capacity()如果在 23.3.6.3 下提及。 23.3.6.3 下没有提到复制分配,因此不会修改 capacity() . (移动分配也有同样的问题,特别是考虑到提议的解决方案 Library DR2321。)

显然,这是标准中的一个缺陷,因为复制分配传播不平等的分配器必须导致重新分配,这与 23.3.6.3p5 相矛盾。

我们可以期待并希望通过以下方式解决这个缺陷:

  • 非还原 capacity()关于非分配器修改复制分配;
  • 未指定 capacity()关于分配器修改拷贝分配;
  • 非还原 capacity()关于非分配器传播的移动分配;
  • 源容器capacity()关于分配器传播的移动分配。

但是,在当前情况下,直到澄清这一点,您最好不要依赖任何特定行为。幸运的是,有一个简单的解决方法可以保证不会减少 capacity() :

bigVector.assign(littleVector.begin(), littleVector.end());

关于c++ - vector 分配是否会使 `reserve` 无效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24260717/

相关文章:

c++ - 如何使用自定义 Vertex 属性读取 GraphML 文件以进行 Boost Graph?

c++ - 在子语句的最外层 block 中重新声明的变量

c++ - 使用 gcc 捕获 lambda 错误,使用 clang 进行编译

c++ - 完整对象还是子对象?

c++ - "Ambiguous conversion sequence"- 这个概念的目的是什么?

c++ - 在 libtidy 中,如何读取字符串值选项

c++ - 使用动态库是否节省内存

c++ - 使用opencv c++进行静态图像车辆识别

c++ - volatile 未按预期工作

c++ - 了解编译时断言