【问题标题】:Is it safe to call vector.resize(0) after moving its content [duplicate]移动内容后调用vector.resize(0)是否安全[重复]
【发布时间】:2016-10-07 15:09:46
【问题描述】:

换句话说就是下面的代码声音(定义的行为,便携,...)

   std::vector<int> vec(100,42);
   std::vector<int> other = std::move(vec);
   vec.resize(0);//is this sound

   //using vec like an empty vector

【问题讨论】:

  • 你可以用vector任何事情,它不需要任何特定的属性(超出有效性)。不过,比起resize(0),我更喜欢clear()

标签: c++ language-lawyer


【解决方案1】:

是的,它是安全的。

来自 §23.3.6.5:

如果sz &lt;= size(),相当于调用pop_back()size() - sz次。如果是size() &lt; sz,则将sz - size() 默认插入的元素附加到序列中。

所以基本上,当您调用resize(0) 时,它会调用pop_back(),直到从向量中删除每个元素。

您移动vec 并不重要,因为即使vec 的状态未指定,它仍然是您可以修改的有效向量。

因此,在调用 resize(0) 后,std::vector 将为空。

【讨论】:

  • 不,你不能调用pop_back(),因为pop_back()有先决条件。但是,size() 没有,一旦你调用了size(),并确保它大于 0,你就检查了向量是否满足pop_back() 的先决条件,所以调用它是安全的.
  • [FYI] 用pop_back 定义resize 是一个defect
【解决方案2】:

从一个对象移动后,您通常不能对对象的状态做出任何假设。这意味着您只能调用没有任何前置条件的成员函数。令人高兴的是,std::vector::resize 没有与值相关的先决条件,因此您可以在已移动的向量上调用 resize

【讨论】:

  • 您通常不能对对象的状态做出任何假设 错误:您可以假设它是有效的。这就是重点。
  • 关于resize的前提条件。 §23.3.6.3 : 13 要求:T 应为 MoveInsertable 和 DefaultInsertable 到 *this。
  • @Walter:这是不言而喻的。每个对象都是有效的。否则它不是一个对象。
  • @vu1p3n0x:这样的对象是不可破坏的,而且析构函数也没有值依赖的前提条件。
  • @Walter:我明白你的意思,当然,我知道很多引用的“有效但未指定”。但我想指出,move 构造和赋值只是普通的成员函数,它们在任何不同于现有约定和设计的方面都没有什么特别之处,也没有什么需要明确指出的。要点是“未指定状态”意味着“可能不满足任何先决条件”。
猜你喜欢
  • 2018-10-02
  • 2015-03-28
  • 2019-11-22
  • 1970-01-01
  • 2019-03-01
  • 2015-12-15
  • 1970-01-01
  • 2017-05-05
  • 1970-01-01
相关资源
最近更新 更多