我的代码中出现的最常见错误之一是在循环期间修改STL容器.
在循环执行期间删除或添加元素,因此我经常遇到超出范围的异常.
我的for循环通常看起来像这样:
for (auto& Item : Items) { // Will not work when Items container is modified
//... loop logic
}
Run Code Online (Sandbox Code Playgroud)
当可以删除多个项目时,我使用这个怪物:
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
}
}
Run Code Online (Sandbox Code Playgroud)
这看起来很糟糕,这让我觉得使用第二个选项感觉很糟糕.可以删除多个项目的原因是由于事件,单个事件可以删除任意数量的元素.
下面是一些伪代码来说明何时发生这种情况:
// for each button in vector<button> {
// process button events
// event adds more buttons to vector<button>
// *ERROR* vector<button> is modified during loop.
// }
Run Code Online (Sandbox Code Playgroud)
在另一个示例中,想象一个包含以下项的向量:
// 0 1 2 3 4 5 6 7 8 9
Run Code Online (Sandbox Code Playgroud)
我们开始循环,0逐个元素地去.在4,我想删除的元素1,4并且9因此我们不能在这里使用一个正常的循环.
std::remove_if与谓词一起使用,该谓词决定是否需要删除按钮:
bool needsRemoved(const Button& button);
vec.erase(std::remove_if(vec.begin(), vec.end(), &needsRemoved), vec.end());
Run Code Online (Sandbox Code Playgroud)
编辑:对于您的上一个示例,二次(即性能不佳)算法是:
std::vector<int> vec = {0,1,2,3,4,5,6,7,8,9};
auto end = vec.end();
for (auto it = vec.begin(); it < end; ++it)
{
std::set<int> bad = {1, 4, 9};
end = std::remove_if
(vec.begin(), end,
[bad](int x) { return (bad.find(x) != bad.end()); });
}
vec.erase(end, vec.end());
Run Code Online (Sandbox Code Playgroud)
您可能最好使用快速查找的容器(如集合或地图).
| 归档时间: |
|
| 查看次数: |
1065 次 |
| 最近记录: |