根据 Stroustrup:C ++编程语言: -
“当 vector 调整大小以容纳更多(或更少)元素时,其所有元素都可能是 搬到了新的地方。“
这是否成立,即使将矢量调整为较小的尺寸?
答案 0 :(得分:4)
案例1:如果请求的新尺寸大于当前std::vector::capacity()
,则所有元素都将重新定位。
案例2:如果请求的新大小小于当前std::vector::capacity()
,则不会重新定位元素。
Standerdese Evidence:
该标准将vector::resize()
的效果定义为:
C ++ 11标准23.3.6.3/12向量容量:
void resize(size_type sz, const T& c);
效果:
if (sz > size())
insert(end(), sz-size(), c);
else if (sz < size())
erase(begin()+sz, end());
else
; // do nothing
正如@DavidRodríguez-dribeas正确指出的,std::vector::insert()
操作的迭代器失效规则是:
23.3.6.5向量修饰符
1 [insert,push_back,emplace,emplace_back]
备注:如果新大小大于旧容量,则会导致重新分配。如果没有重新分配,插入点之前的所有迭代器和引用仍然有效。
基本上这意味着:
除非新容器大小大于先前容量,否则插入点之前的所有迭代器和引用都不会受到影响,因为在这种情况下,所有元素都可能被移动到新位置,从而使指针/迭代器无效到原始位置。自 resize()
仅在容器末尾删除/插入元素 [注释1] 。管理因素归结为请求的大小与当前容量相对应。
因此案例1结果。
案例2 std::vector::erase()
将被调用,此案例中的失效规则为:
23.3.6.5向量修饰符
迭代器擦除(const_iterator位置);
3效果:使擦除点处的在<或>之后>>使迭代器和参考值无效。
自 [注1] 以来,元素只会在结尾删除,不需要重新定位所有元素。
答案 1 :(得分:1)
...元素可能会移动到新的位置。“
请注意可能会被移动。所以这意味着它取决于它是什么类型的调整大小。
答案 2 :(得分:1)
向量中的迭代器因两个原因而失效。如果向量需要增加其容量,则在迭代器(1)的位置或整个缓冲区重新定位(2)之前插入/移除元素。这里的关键是对capacity()
的更改。
因为resize()
仅从容器的末尾插入/删除。当向量收缩时,只有那些引用被删除元素的迭代器才会失效。当向量增长时,如果新大小小于capacity()
,则迭代器将无效,并且如果新大小较大,则所有迭代器将无效。
由于Als提供了错误的证据 1 ,我在这里添加了正确的引号:
23.3.6.5向量修饰符
1 [insert,push_back,emplace,emplace_back]
备注:如果新大小大于旧容量,则会导致重新分配。如果没有重新分配,插入点之前的所有迭代器和引用仍然有效。
2 [擦除]
效果:使擦除点处的在<或>之后>>使迭代器和引用无效。
类似的引用可以在C ++ 03中找到。
1 避免复制指示resize
与插入或擦除等效的引用。哪个是对的。
答案 3 :(得分:0)
问题正文中的答案“”当向量调整大小以容纳更多(或更少)元素时,其所有元素都可能是搬到了新的地方。“”