递减 std::vector::begin 是否未定义,即使它从未被使用过?

Is decrementing std::vector::begin undefined, even if it is never used?

本文关键字:vector std begin 是否 未定义 递减      更新时间:2023-10-16

请注意,与关于该主题的许多问题相反(可能以及为什么我在谷歌和堆栈溢出上都找不到这个问题的满意答案(,我从不取消引用*(begin() - 1)


我的要求是:

  • 向后迭代
  • 使用不采用反向迭代器的函数,在此示例中vector::erase()
  • 尽量保持代码干净,所以尽量避免以下方面的心理杂耍:

    vector.erase(rev_it.base() - 1)

    (反向迭代器现在应该是什么才能获得迭代中的下一个元素?迭代器返回的erase()+ 1,大概吗?- 1,不太可能?

我想出的是:

for (auto it = vector.end(); it-- != vector.begin(); ) {
if (condition(*it)) {
it = vector.erase(it);
}
}

这似乎有效,因为it--返回迭代器的值,然后只递减它,这意味着迭代器总是在检查之后但在进入循环体之前递减。

特别:

进入循环时

  • 如果vector.end() == vector.begin()向量为空,我们立即退出循环
  • 如果vector.end() != vector.begin()则我们进入循环,第一个循环体执行it == vector.end() - 1

擦除元素时

vector.erase(it)返回向量中的以下元素,因此在每次迭代时递减迭代器可以让我们精确地考虑一次向量中的每个元素。

退出循环时

在循环主体的最后一次执行中,it == vector.begin(),所以下次我们尝试循环条件时:

  • 条件返回false
  • it最后一次递减
  • 我们退出循环

也就是说,我的代码似乎确实计算了迭代器的位置begin() - 1从未访问过它也没有将其用于比较或类似的事情。

这是未定义的行为吗?

我冒着段错误或其他风险吗?或者只是访问未初始化的数据?什么都没有,因为迭代器在使用之前被丢弃了?没有办法知道吗?

怎么样

for (auto it = vector.end(); it != vector.begin(); ) {
--it;
... rest of the loop body
相关文章: