考虑以下函数
void removeOdd(list<int>& li)
{
for(list<int>::iterator it=li.begin(); it!=li.end(); it++)
{
if((*it)%2) it = li.erase(it);
}
}
根据我对列表的理解,其中返回值是一个“指向函数调用删除的最后一个元素后面的元素的迭代器”,
removeOdd() 函数应该在删除元素后忽略该元素并继续遍历列表。
但是,当链接到此测试脚本时
#include <list>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cassert>
using namespace std;
void test()
{
int a[9] = { 5, 2, 8, 9, 6, 7, 3, 4, 1 };
list<int> x(a, a+9); // construct x from the array
assert(x.size() == 9 && x.front() == 5 && x.back() == 1);
removeOdd(x);
assert(x.size() == 4);
vector<int> v(x.begin(), x.end()); // construct v from x
sort(v.begin(), v.end());
int expect[4] = { 2, 4, 6, 8 };
for (int k = 0; k < 4; k++){
assert(v[k] == expect[k]);
}
}
int main()
{
test();
cout << "Passed" << endl;
}
它过去了。此外,将removeOdd()修改为
void removeOdd(list<int>& li)
{
for(list<int>::iterator it=li.begin(); it!=li.end(); it++)
{
if((*it)%2){
cout << *it << " ";
it = li.erase(it);
cout << *it << endl;
}
else cout << *it << endl;
}
}
并在我的 WSL 实例上运行整个脚本(使用 g++ 编译),会产生以下输出:
5 2
8
9 6
7 3
4
1 5
2
8
6
3 4
Passed
我是否遗漏了某些内容,或者列表迭代器是否循环回到列表中?
我尝试在线阅读有关 std::list.erase() 和随机访问迭代器的文档,但仍然无法理解上述行为。
在
removeOdd
中,即使删除项目,也会增加 it
。您只需要为不删除的项目增加它,例如:
void removeOdd(list<int>& li)
{
for(list<int>::iterator it = li.begin(); it != li.end(); )
{
if (*it % 2) it = li.erase(it);
else ++it:
}
}