vector擦除迭代器
我有这个代码:
int main() { vector<int> res; res.push_back(1); vector<int>::iterator it = res.begin(); for( ; it != res.end(); it++) { it = res.erase(it); //if(it == res.end()) // return 0; } }
“一个随机访问迭代器指向元素的新位置,后面跟着被函数调用擦除的最后一个元素,如果操作删除了序列中的最后一个元素,则这是向量结尾。
此代码崩溃,但如果我使用if(it == res.end()),然后返回它的作品。 怎么来的? for循环是否获取res.end()以便不等于运算符失败?
res.erase(it)
总是返回下一个有效的迭代器,如果你删除了它指向的最后一个元素.end()
在循环结束时, ++it
总是被调用,所以你增加.end()
这是不允许的。
简单地检查.end()
仍然会留下一个错误,因为每次迭代都会跳过一个元素( it
会从.erase()
返回,然后再由循环重新获得)
你可能想要像这样的东西:
while (it != res.end()) { it = res.erase(it); }
擦除每个元素
(为了完整性:我假设这是一个简单的例子,如果你只是想让每一个元素都不res.clear()
执行操作(例如删除),你应该简单地调用res.clear()
)
当你只是有条件地擦除元素,你可能想要类似的东西
for ( ; it != res.end(); ) { if (condition) { it = res.erase(it); } else { ++it; } }
for( ; it != res.end();) { it = res.erase(it); }
或者更一般的:
for( ; it != res.end();) { if (smth) it = res.erase(it); else ++it; }
作为crazylammer的回答的修改,我经常使用:
your_vector_type::iterator it; for( it = res.start(); it != res.end();) { your_vector_type::iterator curr = it++; if (something) res.erase(curr); }
这样做的好处是,你不必担心忘记增加你的迭代器,当你有复杂的逻辑时,减less错误的可能性。 在循环内部,curr永远不会等于res.end(),它将在下一个元素处,无论你是否从你的向量中删除它。
不要擦除然后递增迭代器。 没有必要增加,如果你的向量有一个奇怪的(甚至,我不知道)数量的元素,你会错过向量的结尾。
it ++指令在块的末尾完成。 所以如果你正在擦除最后一个元素,那么你尝试增加指向一个空集合的迭代器。
在for循环的循环expression式中,将it
增加到(空)容器的末尾。
以下也似乎工作:
for (vector<int>::iterator it = res.begin(); it != res.end(); it++) { res.erase(it--); }
不知道这是否有缺陷?
if(allPlayers.empty() == false) { for(int i = allPlayers.size() - 1; i >= 0; i--) { if(allPlayers.at(i).getpMoney() <= 0) allPlayers.erase(allPlayers.at(i)); } }
这对我有用。 而且不需要考虑索引已经被删除。