是否定义良好定义修改foreach循环中的unordered_set如果之后立即爆发?

mer*_*011 4 c++ iterator unordered-set c++11

考虑以下程序.中间的循环尝试用一个其他项目恰好替换一个项目,然后突破循环.

#include <unordered_set>
#include <stdio.h>

int main(){
    std::unordered_set<int> foo{1,2,3};
    printf("Set Before:\n");
    for (int x : foo)
        printf("%d\n", x);
    for (int x : foo) {
        if (x == 1) {
            foo.erase(1);
            foo.insert(4);
            break;
        }
    }
    printf("Set After:\n");
    for (int x : foo)
        printf("%d\n", x);
}
Run Code Online (Sandbox Code Playgroud)

上面的代码定义明确吗?

Bar*_*rry 10

上面的代码定义明确吗?

是.擦除会使你现在正在使用的迭代器无效,这将使其后续增加未定义的行为 - 但是没有后续的增量,因为你是break无条件的.


虽然不是在找到之前循环遍历每个元素1,但您可以尝试擦除它并查看它是否有效:

if (foo.erase(1)) {
    foo.insert(4);
}
Run Code Online (Sandbox Code Playgroud)


Yak*_*ont 5

for(type var:target) 循环定义为等效于:

{
  auto&& __target = target;
  auto&& __start = __magic_begin(__target);
  auto&& __finish = __magic_end(__target);
  for (; __start != __finish; ++__start) {
    type var = *__start;
    __body_of_loop_here__
  }
}
Run Code Online (Sandbox Code Playgroud)

哪里__magic_begin是一个魔术函数,它可以用来查找begin迭代器,其详细信息在这里无关紧要.(另外,__前缀名称仅用于说明目的).

由于您的代码是使用上述转换定义的,因此在没有它的情况下定义它.

标准中的大多数事情并非如此明确; 这个真的是.

甚至还有上述转变造成的错误.例如,如果target临时表不是表达式的结果,则它们的生命周期在__start创建迭代器之前结束.