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. 基于 HTML5 + WebGL 的无人机 3D 可视化系统

    前言 近年来,无人机的发展越发迅速,既可民用于航拍,又可军用于侦察,涉及行业广泛,也被称为“会飞的照相机”.但作为军事使用,无人机的各项性能要求更加严格.重要.本系统则是通过 Hightopo 的   ...

  2. Liquibase 使用(全)

    聊一个数据库脚本的版本工具 Liquibase,官网在这里 ,初次看到,挺神奇的,数据库脚本也可以有版本管理,同类型的工具还有 flyway . 开发过程经常会有表结构和变更,让运维来维护的话,通常会 ...

  3. tomcat+jdk安装部署

    安装tomcat tar zxf jdk-8u66-linux-x64.tar.gz mkdir /application/java/ -p mv /home/oldboy/tools/jdk1.8. ...

  4. 跟我一起学QT_QT标准对话框_文件对话框

    标准对话框 QT的标准对话框分为以下几种 颜色对话框 文件对话框 字体对话框 输入对话框 消息对话框 进度对话框 错误信息对话框 向导对话框 文件对话框 QT中的文件对话框QFileDialog类提供 ...

  5. 使用rapidjson把文本json数据解析到树状结构

    一个递归搞定 无聊的时候练练手就写了一个 头文件什么的我就不贴了 demo程序是MFC写的 void ParseObject(rapidjson::Value dc, CTreeCtrl * pTre ...

  6. 洛谷$P2598\ [ZJOI2009]$狼和羊的故事 网络流

    正解:网络流 解题报告: 传送门! 昂显然考虑最小割鸭$QwQ$,就考虑说每个土地要么属于羊要么属于狼,然后如果一条边上是栅栏一定是相邻两边所属不同. 所以考虑给所有羊向$S$连$inf$,所有狼向$ ...

  7. 机器学习回顾篇(13):集成学习之AdaBoost

    .caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1px so ...

  8. 1052 卖个萌 (20 分)C语言

    萌萌哒表情符号通常由"手"."眼"."口"三个主要部分组成.简单起见,我们假设一个表情符号是按下列格式输出的: [左手]([左眼][口][右 ...

  9. 组件与props简解

    一.创建组件 1.函数式创建 特点: 组件不能访问this对象 组件无法访问生命周期的方法 无状态组件只能访问输入的props,无副作用 function Title() { return <h ...

  10. 使用JavaMail发送邮件(含文本/附件/图片)的工具类

    记录利用公司内搭建的smtp邮件服务器,使用javax mail发送邮件的程序 package com.test.mailTest; import java.util.Date; import jav ...