C++范围for遍历std::list时循环内追加元素能否覆盖全部元素?
问题解答
代码行为结论
你给出的代码无法收集到所有层级的后续进程,范围for循环也不会遍历到循环过程中新追加的元素,核心原因如下:
- C++标准规定范围for循环会在执行前预先获取容器的
begin()和end()迭代器,整个循环的终止条件固定为「当前迭代器不等于初始获取的end()」 - 虽然
std::list::insert不会让已有迭代器失效,但循环开始时获取的初始end()迭代器,始终指向列表初始化完成时的末尾位置,后续插入的元素全部在该初始end的后方,永远不会被范围for遍历到 - 最终生成的列表
n仅会包含初始f_next的一级子进程,以及这些一级子进程的直接子进程,更深层级的进程会全部遗漏
正确实现方案
改用手动控制的迭代器循环,每次判断终止条件时都获取当前最新的末尾迭代器,即可遍历所有后续插入的元素:
list_t n(f_next); auto it = n.begin(); while (it != n.end()) { n.insert(n.end(), it->f_next.begin(), it->f_next.end()); ++it; }
额外注意事项
- 上述方案仅适用于进程依赖链无环的场景,如果存在循环依赖(比如A的后续是B、B的后续又是A),会导致无限插入元素,最终触发内存溢出
- 如果需要兼容有环的场景,可以额外引入
std::unordered_set<process*>记录已经处理过的进程指针,遇到重复的进程直接跳过插入即可
内容的提问来源于stack exchange,提问作者Alexis Wilke
相关产品推荐
相关产品推荐

