根据这个非常受欢迎的答案,遍历一组擦除某些元素的规范方法如下:
for (it = mySet.begin(); it != mySet.end(); ) {
if (conditionToDelete(*it)) {
mySet.erase(it++);
}
else {
++it;
}
}
当然,这是 C++03 的 set erase 没有返回迭代器的结果。否则可以写 可以写it = mySet.erase(it);
也很明显
itToDelete = it++;
mySet.erase(itToDelete);
这个问题不是关于如何在迭代时删除元素。问题是为什么以下行显然不会导致未定义的行为。
mySet.erase(it++);
起初我确信这一定是 UB,因为我对后增量的想法是错误的。这是一种常见(但错误)的方式,将预增量视为在其余评估之前发生,而后增量发生在之后。当然,这是错误的。postincrement 和 preincrement 都有增加变量的副作用。不同之处在于这些表达式的值。
也就是说,据我所知,C++ 标准(至少是 C++03 标准)没有具体说明后增量的副作用何时发生。所以,除非我们有保证,如果作为后增量表达式的函数参数在进入函数体之前会产生副作用,那么这不应该是 UB 吗?究竟是什么(标准方面)(如果有的话)禁止在迭代器在函数体内无效后发生 it++ 的副作用?
来自标准的报价将非常受欢迎。
为了论证的缘故,我们还假设 set 的迭代器是内置类型,这实际上是 operator ++,而不是重载的 operator-function