用set、map等存储自定义结构体时容器内部判别各元素是否相同的注意事项

STL做为通用模板极大地方便了C++使用者的编程,由于它能够存储任意数据类型的元素编程

若是咱们想用set与map来存储自定义结构体时,以下函数

struct pp { double xx; double yy; }; set<pp> aa[25]; struct ab { double aa; double bb; double cc; }stra[25]; map<ab, int> mm;

上面咱们使用 set 来存储 pp结构体,将 ab结构体做为一个映射的Keyspa

显然咱们这样作编译器会报错,缘由是set与map内部须要比较各个元素的大小,这样咱们的结构体缺失了小于号的重载,没法存储code

 

改后以下:blog

struct pp { double xx; double yy; bool operator < (const pp a)const    //重载小于号 
 { return xx < a.xx; } }; set<pp> st; struct ab { double aa; double bb; double cc; bool operator < (const ab a)const    //重载小于号 
 { return aa < a.aa; } }; map<ab, int> mp;

 

这样用经过结构体中的某个数比较来定义结构体的小于号,咱们的程序就编译成功了编译器

但在运行时咱们就会发现一个现象,那就是若是咱们编译

将一个pp结构体模板

 

A(A.xx == 1, A.yy == 2)class

 

插入集合st以后容器

咱们若再插入一个pp结构体

 

B(B.xx == 1,B.yy == 3)

 

后面检查时会发现,集合中只有A而没有B,但插入insert操做是确实执行过的

那么缘由应该只有一个,就是set内部将A与B视为同一个元素,因为set的去重性,第二次加入B不成功。

为什么会认为A,B相同?注意到咱们的小于号重载

bool operator < (const pp a)const    //重载小于号 
{ return xx < a.xx; }

 

要知道上面咱们仅仅用pp结构体成员xx来定义小于号,因此因为A,B的xx相同(都是1),set内部认为A,B相同(即便A,B的yy值不相同)

 

相似地,咱们若是给map里面加上两对 “键-值”

而这两个键(都是ab结构体)的成员aa相同而bb与cc不相同的话

咱们的mp映射里面也会只有一对“键-值”,(并且值是后一个加入的值覆盖掉了前面的值)

 

解决方法就是修改小于号重载函数,使得结构体成员有一个不相同时,return后面的表达式就不能相等

举例以下

struct pp { double xx; double yy; bool operator < (const pp a)const { return xx * yy - xx / yy + yy / 2.745 < a.xx * a.yy - a.xx / a.yy + a.yy / 2.745;    //用于集合的必备操做
 } }; set<pp> aa[25]; struct ab { double aa; double bb; double cc; bool operator < (const ab a)const { return aa * cc / 5.123 + bb / 3.145 - aa < a.aa * a.cc / 5.123 + a.bb / 3.145 - a.aa;//用于映射的必备操做
 } } map<ab, int> mm;

可看出,新的重载方式囊括告终构体内部的全部成员,而且使用了三位小数,确保了只有在两个结构体内部成员彻底同样时容器内部才会判为相同元素,出现错误的几率被降到极低。

 

因此能够在表面现象上肯定的是,set与map内部不只用小于号来判断元素大小,并且也用它来判断元素是否相同

保证重载小于号的返回表达式的比较值对于不一样元素具备真正的辨别性,是用这些容器来装载自定义结构体所须要注意的事项

相关文章
相关标签/搜索