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

时间:2019-05-09 15:34:40

标签: c++ c++98

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

我有一个向量类。我想做的是,当类成员的变量之一(例如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,则会出现问题。我想从向量中删除该元素,但还可以安全地退出迭代。在上面的实例中,我可以在将break设置为vect1.erase(it)之后将其放入,但是例如,如果我的擦除操作位于迭代循环内的一个开关内,则此操作将无效。当它离开switch语句时,将需要一个条件变量从那里退出。

因此,我想知道是否有一种方法可以不需要我使用break来防止如果我要在switch语句中擦除时避免出现混乱的代码?

1 个答案:

答案 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在删除元素之后已经向元素返回了迭代器,因此您不应该对其进行递增。