从标准::列表中删除/擦除
remove/erase from std::list
可能的重复项:
如何从标准::地图中过滤项目?
标准::列表::擦除不起作用
我有一些关于删除,擦除的愚蠢问题 std::list.
我有一个定义为:
class CBase
{
public:
CBase(int i): m(i)
{};
int m;
};
然后,我将其设置为:
list<CBase> ml;
CBase b1(1);
CBase b2(2);
CBase b3(3);
CBase b4(4);
ml.push_back(b1);
ml.push_back(b2);
ml.push_back(b3);
ml.push_back(b4);
我可以擦除 m==2 的项目;
for (list<CBase>::iterator it=ml.begin(); it!=ml.end(); ++it)
{
if (it->m == 2)
{
ml.erase(it--);
}
}
// show what we have now:
for (list<CBase>::iterator it=ml.begin(); it!=ml.end(); it++)
{
cout << it->m;
}
但如果我这样做:
for (list<CBase>::iterator it=ml.begin(); it!=ml.end(); it++)
{
if (it->m == 2)
{
ml.erase(it);
it--;
}
}
会有例外。这是为什么呢?
如果我想删除 b3,
ml.remove(b3);
不会编译。我在网上找到的所有示例都使用list<int>
,如果mylist is list<int>
,调用mylist.remove(3)
没有问题。我怎样才能让它工作?
您正在取消引用指向已擦除元素的迭代器。使用 erase()
成员函数的返回值:
it = ml.erase(it);
// 'it' now points at first element after the last deleted element
因为擦除会使迭代器失效。它可能不再使用,包括递减运算符。
编辑:至于删除,它会删除值等于您指定的元素。 std::list
使用operator==
进行比较,除非您定义了它,否则编译将失败。只需定义运算符,应该没问题。
在erase
之后,你传递给它的迭代器将是无效的。
现在,使用
ml.erase(it--);
您正在传递迭代器的副本erase
并向后移动副本,以便它不再引用列表中的同一位置。--
发生在erase
的副本准备好之后,但在实际调用erase
之前。
调用后,迭代器仍然有效,并且它比您删除的元素早一个位置。
但如果你这样做
ml.erase(it);
it--;
it
在调用后仍在尝试引用已删除的元素,当您尝试修改它时,您会收到异常,因为它无效。
相关文章:
- C++14 中unordered_map矢量和擦除删除成语的奇怪行为
- 擦除是否删除 stl 无序列图元素使用的堆内存
- 当我不关心顺序并且没有重复项时,更快的擦除删除成语?
- 如何使用擦除和迭代器来删除二维向量中的项目
- 擦除删除成语的性能增益从何而来
- 矢量擦除错误,无法删除不完整的类型
- 为什么擦除+删除比删除更有效
- 如何根据某些值擦除/删除类对象的向量
- 为什么擦除-删除成语不适用于反向迭代器
- C++擦除-删除类型推断失败
- 使用擦除-删除范例将元素从一个向量移动到另一个向量
- 如何使用擦除删除习语从结构向量中删除值
- 有没有办法将擦除-删除成语与其他循环条件一起使用
- 对2D或3D矢量使用擦除-删除习惯用法
- 使用类型擦除删除C++11中的void*
- 为什么标准中没有提供擦除-删除习惯用法的便利助手
- 在c++中使用擦除-删除习语时,我应该通过引用传递吗?
- 对函数使用擦除-删除习惯用法<void(>
- 如何使用擦除-删除习惯用法并在循环中增加迭代器
- 如何在排序的向量上正确应用擦除-删除习惯用法