从multiset的lower_bound迭代器遍历删除元素报错问题排查
问题:multiset删除目标元素时的迭代器错误及返回值疑问
我希望从multiset中目标值的lower_bound迭代器开始,删除所有该目标值的出现,再继续遍历后续元素。编写了如下代码:
multiset<int> s={....}; auto it=s.lower_bound(target); while(it!=s.end()){ if(s.find(target)!=s.end()) it=s.erase(target); else it++; }
运行时报错:
Line 36: Char 12: error: no viable overloaded '=' it4=x.erase(99); ~~~^~~~~~~~~~~~ /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_tree.h:326:12: note: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'std::set<int, std::less<int>, std::allocator<int>>::size_type' (aka 'unsigned long') to 'const std::_Rb_tree_const_iterator<int>' for 1st argument struct _Rb_tree_const_iteratorrgument
请问s.lower_bound(target)和s.erase(target)返回的迭代器有什么区别?我需要保持这种遍历方式来实现需求,已知另一种循环查找删除的方法但不想使用。
一、lower_bound与erase(target)的返回值差异
s.lower_bound(target):返回迭代器,指向multiset中第一个不小于target的元素,类型为std::multiset<int>::iterator(或const迭代器)。s.erase(target):这是按值删除的重载版本,返回被删除元素的数量,类型为size_type(本质是无符号整数)。你报错的核心原因就是把整数类型赋值给了迭代器变量,类型完全不匹配。
二、符合需求的修正代码
要实现从lower_bound位置开始删除所有目标值,再遍历后续元素,需使用迭代器版本的erase,同时无需每次调用find(因为已经从目标值的起始位置开始遍历):
multiset<int> s = {....}; auto it = s.lower_bound(target); while (it != s.end()) { if (*it == target) { // 迭代器版erase删除当前元素,返回指向后续第一个元素的迭代器 it = s.erase(it); } else { // 非目标元素,直接移动迭代器 ++it; } }
说明
- 迭代器版本的
erase(it)会删除当前迭代器指向的元素,并返回指向被删除元素下一个位置的迭代器,直接用这个返回值更新it即可,无需手动自增。 - 由于我们从
lower_bound(target)开始遍历,前面的元素都小于目标值,因此只需从当前位置向后判断是否等于目标值,效率更高。
内容的提问来源于stack exchange,提问作者Arsh
相关产品推荐
相关产品推荐

