STL作为通用模板极大地方便了C++使用者的编程,因为它可以存储任意数据类型的元素

如果我们想用set与map来存储自定义结构体时,如下

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

上面我们使用 set 来存储 pp结构体,将 ab结构体作为一个映射的Key

显然我们这样做编译器会报错,原因是set与map内部需要比较各个元素的大小,这样我们的结构体缺失了小于号的重载,无法存储

改后如下:

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)

插入集合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[]; 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内部不仅用小于号来判断元素大小,而且也用它来判断元素是否相同

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

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

  1. Solidity的自定义结构体深入详解

    一.结构体定义 结构体,Solidity中的自定义类型.我们可以使用Solidity的关键字struct来进行自定义.结构体内可以包含字符串,整型等基本数据类型,以及数组,映射,结构体等复杂类型.数组 ...

  2. gin中绑定表单数据至自定义结构体

    package main import "github.com/gin-gonic/gin" type StructA struct { FieldA string `form:& ...

  3. typedef和自定义结构体类型

    在自定义结构体类型时会用到typedef关键字.大家都知道typedef是取别名的意思,在C语言中跟它容易混淆的有const,#define等,其区别不在本篇文章讨论之列. /*定义单链表结点类型*/ ...

  4. qsettings 保存自定义结构体(QVariant与自定义结构体相互转化)

    参考博文:QVariant与自定义数据类型转换的方法. 这里摘取其关键内容: 1.将自定义数据类型使用Q_DECLARE_METATYPE宏进行声明,便于编译器识别. 2.在插入对象的时候,声明QVa ...

  5. iOS自定义结构体

    一.提要 通过以官方的CGSize为例,自定义Objective-C中的结构体,并使用. 二.CGSize 1.系统定义的CGSize结构体 struct CGSize { CGFloat width ...

  6. Qt--信号槽传递自定义结构体参数

    自定义结构体参数的信号槽连接 (1) 对于自定义的结构体参数,信号槽无法识别参数,导致信号槽连接不起作用.所以需要注册结构体参数.在结构体中声明结束的地方加上结构体注册. struct DealDet ...

  7. 使用类/结构体时关于ZeroMomery用法错误

    今天同事在写了如下结构体: typedef struct _tagInfo { std::list<int> lst; std::vector<int> nVec; } INF ...

  8. QT:用QSet储存自定义结构体的问题——QSet和STL的set是有本质区别的,QSet是基于哈希算法的,要求提供自定义==和qHash函数

    前几天要用QSet作为储存一个自定义的结构体(就像下面这个程序一样),结果死活不成功... 后来还跑到论坛上问人了,丢脸丢大了... 事先说明:以下这个例子是错误的 #include <QtCo ...

  9. 再谈:自定义结构体的对齐问题之__attribute__ ((packed))方法【转】

    转自:https://blog.csdn.net/ipromiseu/article/details/5955295 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.c ...

随机推荐

  1. net core WebApi——依赖注入Autofac

    目录 前言 Autofac 添加一个Util来随时调用 小结 代码地址 前言 周末加班,下午犯困,整理下之前鼓捣过的东西,看过我之前的webapi系列的读者知道,我之前试过Aspect,但是升级到3. ...

  2. 洛谷$P$2518 计数 $[HAOI2010]$ 数位$dp$

    正解:数位$dp$ 解题报告: 传送门$w$ 感觉省选的数位$dp$还是比较有质量的辣,,,至少有一定的思维难度是趴$QwQ$ 这题要考虑到一个,我认为比较关键的点,就,对于一个位数不满的数,可以理解 ...

  3. JDK1.8的HashMap实现原理和源码解析

    哈希表(hash table)也叫散列表,是一种非常重要的数据结构.许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,本文会对java集合框架中的对应实现HashMap的 ...

  4. jmeter 5.1版本更新说明

    版本5.1 摘要 新的和值得注意的 不兼容的变化 Bug修复 改进 非功能性变化 已知问题和解决方法 谢谢 新的和值得注意的 核心改进 JDBC测试已得到改进,能够设置init SQL语句并添加与不支 ...

  5. js绑定下拉框数据源

    ··· buildRule:function (ruleId) { var ruleList = internal.ruleList; if(ruleList){ var programme_sel= ...

  6. 变量内容的删除、取代与替换(optional)

    这部分内容非常繁琐且不易记忆且枯燥,用到来查询即可. 1.变量内容的删除 这一部分比较细枝末节,就不再一一手打了,贴范例图片 #:符合取代文字的最短的一个 ##:符合取代文字的最长的一个 2.变量内容 ...

  7. 微信小程序----日期时间选择器(自定义精确到分秒或时段)

    声明 bug:由于此篇博客是在bindcolumnchange事件中做的值的改变处理,因此会出现当你选择时,没有点击确定,直接取消返回后,会发现选择框的值依然改变.造成原因:这一点就是由于在bindc ...

  8. 使用rabbitmq手动确认消息的,定时获取队列消息实现

    描述问题 最近项目中因为有些数据,需要推送到第三方系统中,因为数据会一直增加,并且需要与第三方系统做相关交互. 相关业务 本着不影响线上运行效率的思想,我们将增加的消息放入rabbitmq,使用另一个 ...

  9. 字符串转hash进阶版

    #include<bits/stdc++.h> using namespace std; ,mod=; vector<unsigned> H[mod]; void Add(un ...

  10. 解决a 标签 和 div 标签高度超出的问题

    当a,或div标签里面有内容时,有时候a 或div的高度会超出,此时可以设置a或div的font-size:0: