我对迭代器有点困惑。我想删除一个恰好具有一定值的向量成员,即使它是向量中的唯一元素。
我有一个向量类。我想做的是,当类成员的变量之一(例如width
)具有某个值时,该类实例将从向量中永久删除。假设类仅由构造函数组成,将width
和height
都作为公共函数并使用析构函数作为公共函数。
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,则会出现问题。我想从向量中删除该元素,但还可以安全地退出迭代。在上面的实例中,我可以在将break
设置为vect1.erase(it)之后将其放入,但是例如,如果我的擦除操作位于迭代循环内的一个开关内,则此操作将无效。当它离开switch语句时,将需要一个条件变量从那里退出。
因此,我想知道是否有一种方法可以不需要我使用break
来防止如果我要在switch语句中擦除时避免出现混乱的代码?
答案 0 :(得分:4)
在循环中删除元素时,必须考虑到删除索引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
在删除元素之后已经向元素返回了迭代器,因此您不应该对其进行递增。