C++ 为什么在从向量中删除时需要减少迭代器?

C++ 为什么在从向量中删除时需要减少迭代器?,c++,erase,C++,Erase,我有一个下面的程序。我需要理解为什么我们在使用擦除方法时需要递减指针? 还有没有更好的办法不造成这种混乱 #include <iostream> #include <vector> using namespace std; int main() { vector<int> myvector{ 1, 2, 3, 4, 5, 6, 7, 8, 9 }; for (auto i = myvector.begin(); i != myvect

我有一个下面的程序。我需要理解为什么我们在使用擦除方法时需要递减指针? 还有没有更好的办法不造成这种混乱

#include <iostream>
#include <vector>
using namespace std;
 

int main()
{
    vector<int> myvector{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
 
    for (auto i = myvector.begin(); i != myvector.end(); ++i) {
        if (*i % 2 == 0) {
            myvector.erase(i);
            i--;// why do we need to decrement ?
        }
    }
 
    // Printing the vector
    for (auto it = myvector.begin(); it != myvector.end(); ++it)
        cout << ' ' << *it;
    return 0;
}
#包括
#包括
使用名称空间std;
int main()
{
向量myvector{1,2,3,4,5,6,7,8,9};
对于(自动i=myvector.begin();i!=myvector.end();++i){
如果(*i%2==0){
myvector.erase(i);
我--;//我们为什么要减量?
}
}
//打印矢量
for(auto it=myvector.begin();it!=myvector.end();+it)
库特
我需要理解为什么我们在使用擦除方法时需要递减指针

您没有,也不应该这样做。正确的做法是使用
erase
的返回值。此时,您的程序有未定义的行为,因为您正在修改无效的迭代器

for (auto i = myvector.begin(); i != myvector.end();) {
    if (*i % 2 == 0) {
        i = myvector.erase(i);
    } else {
        ++i;
    }
}
还有没有更好的办法不造成这种混乱

#include <iostream>
#include <vector>
using namespace std;
 

int main()
{
    vector<int> myvector{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
 
    for (auto i = myvector.begin(); i != myvector.end(); ++i) {
        if (*i % 2 == 0) {
            myvector.erase(i);
            i--;// why do we need to decrement ?
        }
    }
 
    // Printing the vector
    for (auto it = myvector.begin(); it != myvector.end(); ++it)
        cout << ' ' << *it;
    return 0;
}


Caleth给了你一个很好的答案,但我要补充一些信息:

for (auto i = myvector.begin(); i != myvector.end(); ++i) {
    if (*i % 2 == 0) {
        myvector.erase(i);
        i--;// why do we need to decrement ?
    }
}
这是你的代码。在我的解释中,让我们相信迭代器只是一个索引(一个int)。它不是,但它可以帮助理解

假设myvector包含整数0..10,然后删除4。一旦删除:

0 1 2 3 5 6 7 8 9 10
现在,想象一下你的循环,你到达for循环的底部,增量i——它现在有5个,但是你跳过检查旧的myvector[5]——现在存储在myvector[4]中——是否符合你的if语句

另一种方法是:

for(自动i=myvector.begin();i!=myvector.end();){ 如果(…)。。。 否则{ ++一,; } }

也就是说,只有在不删除的情况下才增加迭代器。这避免了在删除的项目之后跳过该项目(因为它移动到了被删除的人的位置)


然而,这是一种错误的方法,Caleth对如何正确操作有更好的答案。

在这个{i=myvector.erase(i);}中,现在我指的是下一个有效的还是前一个有效的?@FrançoisAndrieux我的意思是说,对于一个eg自动myiterator=myvector.erase(i),这个“myiterator”在哪里是指现在吗?@unixlover它指的是过去位于被删除元素之后的元素。换句话说,对于
std::vector
,它指的是现在位于被删除元素用来占据的索引处的对象。@FrançoisAndrieux感谢Buddy:)