问题 移动内容后重复调用vector.resize(0)是否安全


这个问题在这里已有答案:


12679
2018-06-07 15:54


起源

你可以做 什么 接着就,随即 vector 不期望任何特定属性(超出有效性)。我更喜欢 clear() 过度 resize(0)但是。 - Walter


答案:


是的,这是安全的。

从§23.3.6.5开始:

如果 sz <= size(),相当于打电话 pop_back()  size() - sz 倍。如果 size() < sz,附加 sz - size() 默认插入序列的元素。

所以基本上,当你打电话 resize(0),它打电话 pop_back() 直到每个元素都从向量中删除。

你搬家没关系 vec,因为即使状态 vec 未指定,它仍然是您可以修改的有效矢量。

所以 std::vector 打电话后会是空的 resize(0)


9
2018-06-07 15:58



不,你不能打电话 pop_back()因为 pop_back() 有先决条件。然而, size() 没有,一旦你打电话 size(),并确保它大于0,你已经检查过向量是否满足前提条件 pop_back(),所以可以安全地调用它。 - Benjamin Lindley
[仅供参考]这是一个 缺陷 界定 resize 就......而言 pop_back。 - NathanOliver


从对象移出后,通常不能对对象的状态做出任何假设。这意味着您只能调用没有任何先决条件的成员函数。令人高兴的是, std::vector::resize 没有依赖于价值的前提条件,所以你可以打电话 resize 在移动的向量上。


5
2018-06-07 16:07



你通常不能对对象的状态做出任何假设  错误:你可以认为它是有效的。这就是重点。 - Walter
至于提到调整大小的前提条件。 §23.3.6.3:13 要求:T应为MoveInsertable和DefaultInsertable为* this。 - Captain Giraffe
@Walter:不言而喻。每个对象都有效。否则它不是一个对象。 - Kerrek SB
@ vu1p3n0x:这样的对象不会被破坏,析构函数也没有依赖于值的前提条件。 - Kerrek SB
@Walter:当然,我明白你的观点,我知道引用得很多的“有效但没有说明”。但是我想指出一下移动构造和赋值只是普通的成员函数,并且它们与现有的约定和设计有任何不同之处,并且没有任何东西需要明确地调用。要点是“未指明的状态”意味着“可能不满足任何先决条件”。 - Kerrek SB