在迭代过程中删除向量的唯一元素?

Removing the only element of a vector during iteration?

本文关键字:唯一 元素 向量 迭代 过程中 删除      更新时间:2023-10-16

我对迭代器有点困惑。我想删除一个恰好具有特定值的向量成员,即使它是向量中唯一的元素。

我有一个类的向量。我想做的是,当类成员的一个变量(例如width)具有一定的值时,该类实例将从向量中永久删除。让我们假设类仅由一个构造函数组成,将widthheight、公共变量和析构函数作为其公共函数。

vector<Rectangle> vect1;
Rectangle memVar1(3, 5);
Rectangle memVar2(6, 10);
vect1.push_back(memVar1);
vect1.push_back(memVar2);

因此,它将遍历向量的所有成员,搜索是否有任何高度为 5。

for(std::vector<myClass>::iterator it = vect1.begin(); it != vect1.end(); ++it) {
if (it->height == 5) {
//delete the element from the vector, and so memVar2 will be the only element and it will be in slot 0 of the vector now.
it = vect1.erase(it);
} 
}

这按预期工作,如果向量中只有一个元素,则会出现问题,该元素恰好具有不需要的高度 5。我想从矢量中删除该元素,但也要安全地退出迭代。在上面的实例中,我可以在将其设置为 vect1.erase(it) 后放入一个break,但是例如,如果我的擦除位于迭代循环内的开关内,这将不起作用,因此当它离开 switch 语句时,我需要有一个条件变量从那里退出。

所以我想知道是否有一种方法不需要我使用break,以防止在 switch 语句内擦除时出现混乱的代码?

在循环中删除元素时,您必须考虑在索引i处删除元素时,下一个元素位于索引i而不是索引i+1处。同样,擦除向量中的元素会使您擦除的位置及其之后的所有迭代器无效(实际上您已经考虑到了这一点)。因此,循环应如下所示:

for(auto it = vect1.begin(); it != vect1.end(); /* no increment here */) {
if (it->height == 5) {
it = vect1.erase(it);
} else {
++it;
}
}

PS:写完答案后才意识到我的解释是假的。正确的解释是,erase确实在您擦除的元素之后向元素返回了一个迭代器,因此您不应该递增它。