即使根据capacity()仍有未使用的空间,std :: vector也可以将其数据移动到emplace_back()的另一个地址吗?

kyn*_*tto 27 c++ vector language-lawyer c++11

是否保证std::vector仅在size()==capacity()调用时移动其数据,push_back()或者emplace_back()否则也可以执行此操作?

Ker*_* SB 30

规范有点间接.capacity指定为:

size_type capacity() const noexcept;
Run Code Online (Sandbox Code Playgroud)

返回:向量可以容纳的元素总数,无需重新分配.

第二部分来自reserve:

reserve(size_type n);
Run Code Online (Sandbox Code Playgroud)

备注:重新分配使引用序列中元素的所有引用,指针和迭代器无效.在调用之后发生的插入期间不应进行重新分配,reserve() 直到插入将使向量的大小大于值的值为止capacity().

由此可以得出结论,如果大小小于容量,则插入不会导致重新分配.

没有单一,直接的声明,如果有备用容量并且您没有明确调用,则向量将不会重新分配reserve.但是,[container.requirements.general]中有一般容器要求:

除非另有说明(显式或通过根据其他函数定义函数),调用容器成员函数或将容器作为参数传递给库函数不应使迭代器无效,或更改该容器中对象的值.

最后,我们描述了插入的效果:

[insert/emplace_back/push_back:]
Run Code Online (Sandbox Code Playgroud)

备注:如果新大小大于旧容量,则会导致重新分配.如果没有重新分配,插入点之前的所有迭代器和引用仍然有效.

将它们放在一起:除非另有说明,否则调用成员函数不会使迭代器失效.重新分配使迭代器无效(reserve如上所述),因此除非另有说明,否则调用成员函数,特别是插入,不会重新分配,对于新大小超过当前容量的情况,给出了一个这样的重写规范. .

  • @NathanOliver:实际上它很好,只是有点散开.见更新. (2认同)

son*_*yao 8

标准的描述不够清楚.

$ 23.3.6.5向量修饰符[vector.modifiers]:

备注:如果新大小大于旧容量,则会导致重新分配.如果没有重新分配,插入点之前的所有迭代器和引用仍然有效.

因此,当std::vector新大小大于当前容量时,肯定会发生添加元素以重新分配,但即使新大小小于或等于当前容量,也不会发生重新分配.无论如何,如果没有发生重新分配,则插入点之前的所有迭代器和对元素的引用必须保持有效,这意味着不会移动数据.

它是相同的insert(),emplace_back(),emplace()push_back().

引用来自cppreference.com作为参考:

如果new size()大于,capacity()则所有迭代器和引用(包括过去的迭代器)都将失效.否则只有过去的结束迭代器无效.

  • 不,我完全相信,其意图是控制两种方式重新分配的能力.这只是略显草率的措辞.否则它会变得疯狂,并且可能有很多现实世界的代码依赖于这种行为. (3认同)