【发布时间】:2013-06-21 08:30:06
【问题描述】:
我的代码中最常见的错误之一是 STL 容器在循环期间被修改。
元素在循环执行期间被删除或添加,所以我通常会遇到越界异常。
我的 for 循环通常如下所示:
for (auto& Item : Items) { // Will not work when Items container is modified
//... loop logic
}
当可以删除多个项目时,我使用这个怪物:
for (int Index=Items.size()-1;Index<=0;Index--) {
if (Index<Items.size()) { //Because multiple items can be removed in a single loop
//... loop logic
}
}
这看起来很糟糕,使用第二个选项让我感觉很糟糕。可以删除多个项目的原因是由于事件,其中单个事件可以删除任意数量的元素。
这里有一些伪代码来说明何时发生这种情况:
// for each button in vector<button> {
// process button events
// event adds more buttons to vector<button>
// *ERROR* vector<button> is modified during loop.
// }
在另一个例子中,想象一个包含以下项目的向量:
// 0 1 2 3 4 5 6 7 8 9
我们从0 开始循环,逐个元素地进行。在4,我想删除元素1、4 和9,所以我们不能在这里使用普通循环。
【问题讨论】:
-
您可以在删除或添加元素时简单地修改迭代器 - 只要您知道修改了多少项以及在哪里修改。
-
@Spook 我通常不知道什么和在哪里,一个事件可以在 for 循环期间随时删除任意数量的元素。
-
好吧,如果你真的不知道何时何地可以删除元素(以及多少),你唯一的选择是复制容器并修改它......否则没有让这个工作的方法。
-
不过,这引出了一个问题,如果按下按钮 4 删除按钮 9,而您实际上删除了它,然后按下按钮 5 应该删除按钮 9... 它是相同的“9”或确实如此删除以前的第 10 个元素?换句话说,您的元素是由键标识还是由它们在容器中的位置标识?