如何解决std :: set :: erase意外删除了3个元素
在最后一个erase
之前,s1
和s2
中的元素是相同的。
erase
的最后一个s2
会删除集合s2
中的3个元素。真是出乎意料。
#include <iostream>
#include <cstdlib>
#include <cassert>
#include <set>
#include <functional>
using namespace std;
struct Ev {
int p = 0;
int l = 0;
int r = 0;
bool open = false;
friend ostream& operator<<(ostream& os,const Ev& ev);
};
ostream& operator<<(ostream& os,const Ev& ev) {
os << "p = " << ev.p << ",l = " << ev.l << ",r = " << ev.r << boolalpha
<< ",open = " << ev.open;
return os;
}
int main() {
auto lr_cmp = [](const Ev& lhs,const Ev& rhs) {
return lhs.r == rhs.l;
};
set<Ev,decltype(lr_cmp)> s1(lr_cmp);
set<Ev,decltype(lr_cmp)> s2(lr_cmp);
assert(s1.insert({0,1,true}).second);
assert(s1.insert({1,3,true}).second);
assert(s1.insert({2,4,true}).second);
assert(s1.insert({0,5,true}).second);
for (const auto& ev : s1) {
cout << ev << endl;
}
assert(s1.erase({3,false}) == 1);
cout << "--------------------------------" << endl;
assert(s2.insert({1,true}).second);
assert(s2.insert({1,true}).second);
assert(s2.insert({0,true}).second);
assert(s2.erase({2,false}) == 1);
assert(s2.insert({2,true}).second);
for (const auto& ev : s2) {
cout << ev << endl;
}
assert(s2.erase({3,false}) == 1);
return 0;
}
这是输出。
p = 0,l = 0,r = 1,open = true
p = 1,l = 1,r = 3,open = true
p = 2,l = 3,r = 4,open = true
p = 0,l = 4,r = 5,open = true
--------------------------------
p = 0,open = true
prog.exe: prog.cc:51: int main(): Assertion `s2.erase({3,false}) == 1' Failed.
Aborted
解决方法
lr_cmp
不是strict weak order。在其他失败中,它不是可传递的。
要求
如果
lr_cmp(a,b)==true
和lr_cmp(b,c)==true
,则lr_cmp(a,c)==true
不是这种情况,例如
Ev a {1,1,3,true};
Ev b {1,4,true};
Ev c {0,5,true};
std::cout << std::boolalpha << lr_cmp(a,b) << lr_cmp(b,c) << lr_cmp(a,c);
因此,程序的行为是不确定的。大概是在擦除lr_cmp
下的等效元素(或某些?),或者找不到要删除的元素。
的表达式
equiv(a,b)
,等于!lr_cmp(a,b) && !lr_cmp(b,a)
{3,false}
等效于{1,true}
和 {0,true}
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。