【发布时间】:2021-11-05 06:52:19
【问题描述】:
set<int> s = {1, 2, 3, 4};
auto it = s.begin();
while (it != s.end()) {
// this correct
s.erase(it++);
// this incorrect
s.erase(it);
it++;
}
为什么上面的代码可以运行?
我对代码运行时的顺序的理解是:
- 执行擦除函数时,迭代器被删除。
- 执行 add 的混乱迭代器,其行为未定义。
但它运行正常,所以我的问题是为什么它可以运行而这些代码有区别?
【问题讨论】:
-
这在文档中:en.cppreference.com/w/cpp/container/set/erase > 对已擦除元素的引用和迭代器无效。这只是未定义的行为,它可能有效,也可能无效,谁知道呢^^
-
@Someprogrammerdude 为什么?它会按预期工作。
-
@SergeyA 将
s.erase(it++)评估为s.erase(it); it = it + 1;或auto temp = it; it = it + 1; s.erase(temp)?定义清楚吗? -
@Someprogrammerdude 是的,我相信它会像你的第二种情况一样被评估,我很确定它会被很好地定义。后修复增量返回原始操作数的值,因此这将被删除 - 但
it已经递增。 -
@SergeyA 看来你是对的:“......与任何参数表达式相关的每个值计算和副作用......在每个表达式执行之前排序或被调用函数体中的语句" (en.cppreference.com/w/cpp/language/eval_order)