c++ - 递减 std::vector::begin 是否未定义,即使从未使用过?
问题描述
请注意,与关于该主题的许多问题相反(可能是为什么我在谷歌和 stackoverflow 上都找不到这个问题的令人满意的答案),我从不取消引用*(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
推荐阅读
- javascript - JavaScript 原型数组成员找不到 undefiend 的推送
- jquery - 如何隐藏显示以增加元素
- macos - 尝试访问 PCI 内存映射寄存器时 OS X 内核崩溃
- javascript - 使用 reloadGrid 时 JQGRID 坚持发布原始 postData 值
- ansible - 需要在 ansible playbook 中使用 get_url 下载最新的战争文件
- c# - C# mongo GridFS:查询文件元数据属性?
- node.js - 是否可以使用单行命令安装依赖项?
- r - 在R中反转变量值
- html - 锚文本超出 div 部分
- solr - solr:如何将 iso8601date 范围转换为 daterange 以进行数据导入