聊聊C++20的三向比较运算符 `<=>`
C++20标准引入了许多新特性,其中之一是三向比较运算符 <=>,也被称为太空船运算符。这个新运算符为C++程序员提供了一种全新的比较对象的方式,它能有效简化比较逻辑,避免编写多个比较运算符重载的情况。
为什么需要三向比较运算符?
在C++20之前,如果要完整地定义一个类型的比较行为,你需要重载四个运算符:==、!=、< 和 >,有时还包括 <= 和 >=。这不仅使得代码冗长,而且增加了出错的可能性,因为需要确保所有这些运算符之间的逻辑一致性是一件不容易的事情。
三向比较运算符引入后,开发者就可以用单一的运算符表达相同的意图。这提高了代码的简洁性和可读性,并有助于减少错误。
三向比较运算符的工作原理
三向比较运算符通过比较两个对象,返回一个表示它们比较结果的值。这个值可以告诉我们两个对象是否相等、一个是否小于另一个,或者一个是否大于另一个。
在C++20中,这个运算符返回的不是简单的整数,而是std::strong_ordering、std::weak_ordering或std::partial_ordering中的一个值,这些都是定义在<compare>头文件中的新类型。
认识新的比较类别
运算符<=>返回的比较类别提供了不同级别的比较保证:
在C++20中引入了三向比较运算符<=>,也称为太空船运算符,它允许在单个操作中进行全面的比较。与这个运算符一起引入的还有几种新的比较类别,分别是std::strong_ordering、std::weak_ordering和std::partial_ordering。这些类别定义了比较的结果类型,并提供了不同的比较保证。
std::strong_ordering
std::strong_ordering是指两个值之间存在强序关系,即可以明确地比较它们的大小。它提供了最强的比较保证,即总是可以确定两个值是相等的、第一个值小于第二个值,还是第一个值大于第二个值。
使用std::strong_ordering的情况下,比较操作符(<=>)将返回std::strong_ordering::equal、std::strong_ordering::less或std::strong_ordering::greater中的一个,分别代表相等、小于和大于。这允许我们对比较结果进行清晰的布尔测试。
例如,基本数据类型(如整型和浮点型)之间的比较通常使用std::strong_ordering。
std::weak_ordering
std::weak_ordering提供了较弱的比较保证,它通常用于那些可以比较等价性,但不能总是完全确定排序关系的场合。例如,在某些情况下,两个不同的对象可能被视为等价的,尽管它们并不完全相等。
std::weak_ordering返回std::weak_ordering::equivalent、std::weak_ordering::less或std::weak_ordering::greater中的一个。std::weak_ordering::equivalent表示两个值在某种意义上是等价的,不一定意味着它们是相等的,但在排序中可以被视为等价。
例如,当比较忽略大小写的字符串时,两个字符串可能具有weak_ordering,因为在不考虑大小写的情况下,它们可以被视为等价的。
std::partial_ordering
std::partial_ordering是最弱的比较保证,它用于那些可能没有完整排序关系的场合。在这种比较中,一些值可能无法相互比较,比如浮点数中的NaN(Not a Number)值。
std::partial_ordering返回std::partial_ordering::less、std::partial_ordering::equivalent、std::partial_ordering::greater或std::partial_ordering::unordered中的一个。std::partial_ordering::unordered表示两个值之间没有可定义的顺序。
例如,浮点数比较可能返回partial_ordering,因为如果任意一个操作数是NaN,那么比较结果就是无序的。
这三种比较类别允许C++程序员更准确地指定他们的类或结构体比较操作的语义和行为。通过在operator<=>的实现中返回适当的比较类别,我们可以为使用我们类型的代码提供清晰的比较语义,增加了代码的可读性和健壮性。这些新特性是C++20标准提供的类型系统增强的一部分,让C++程序更加安全、清晰且易于维护。
使用三向比较运算符
在自己的类中使用三向比较运算符很简单。你可以通过在类内声明一个返回三向比较结果的operator<=>来实现。例如:
#include <compare>class MyValue {
public:int value;auto operator<=>(const MyValue&) const = default;
};
在这个例子中,MyValue类默认地定义了三向比较运算符。现在,我们可以使用<=>来比较MyValue的实例,并使用结果进行进一步的比较:
MyValue a{5}, b{10};
auto result = a <=> b;
if (result < 0) {// a 小于 b
} else if (result > 0) {// a 大于 b
} else {// a 等于 b
}
结语
与模块(Modules)、协程(Coroutines)、概念(Concepts)等特性相比,三相比较运算符似乎微不足道,但从这一个小小的三相比较运算符的引入,我们可以看到C++的复杂之处与细心之处,因为周边的配套类型(std::strong_ordering、std::weak_ordering和std::partial_ordering)为比较语言提供了严格复杂的抽象,有助于编写出更清晰、更健壮的代码。通过三相比较运算符,我们也能一窥现代C++的发展趋势,提供了一种更为高效和直观的比较方法,也在语言层面上极大地简化了开发者的工作。
相关文章:
聊聊C++20的三向比较运算符 `<=>`
C20标准引入了许多新特性,其中之一是三向比较运算符 <>,也被称为太空船运算符。这个新运算符为C程序员提供了一种全新的比较对象的方式,它能有效简化比较逻辑,避免编写多个比较运算符重载的情况。 为什么需要三向比较运算符…...
CVE-2024-0603 漏洞复现
CVE-2024-0603 源码:https://gitee.com/dazensun/zhicms 开题: CVE-2024-0603描述:ZhiCms up to 4.0版本的文件app/plug/controller/giftcontroller.php中存在一处未知漏洞。攻击者可以通过篡改参数mylike触发反序列化,从而远程…...
西部智慧健身小程序+华为运动健康服务
1、 应用介绍 西部智慧健身小程序为用户提供一站式全流程科学健身综合服务。用户通过登录微信小程序,可享用健康筛查、运动风险评估、体质检测评估、运动处方推送、个人运动数据监控与评估等公益服务。 2、 体验介绍西部智慧健身小程序华为运动健康服务核心体验如…...
Spring Boot中如何处理异步任务
Spring Boot中如何处理异步任务 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将探讨在Spring Boot应用中如何处理异步任务,以提升系统的性…...
数字化精益生产系统--RD研发管理系统
R&D研发管理系统是一种用于管理和监督科学研究和技术开发的软件系统,其设计和应用旨在提高企业研发活动的效率、质量和速度。以下是对R&D研发管理系统的功能设计:...
鱼眼相机 去畸变
目录 枕形畸变和去枕形畸变 去枕形畸变失败 枕形畸变和去枕形畸变 import cv2 import numpy as np import matplotlib.pyplot as plt# 创建一个带网格的原始图像 def create_grid(image_size512, grid_size20):image np.zeros((image_size, image_size, 3), dtypenp.uint8)…...
DC/AC电源模块:为智能家居设备提供恒定的电力供应
BOSHIDA DC/AC电源模块:为智能家居设备提供恒定的电力供应 DC/AC电源模块是一种常见的电源转换器,它将直流电源(DC)转换为交流电源(AC),为智能家居设备提供恒定的电力供应。在智能家居系统中&a…...
小红书运营教程02
小红书大致会分享10篇左右。微博、抖音、以及视频剪辑等自媒体运营相关技能以及运营教程相关会陆续的进行分享。 上次分享涉及到的对比,母婴系列,或者可以说是服装类型,不需要自己过多的投入,对比知识类博主来说,自己将知识讲述出来,然后要以此账号进行变现就比较麻烦,…...
k8s自动清理节点服务
要在 Kubernetes 中实现当某个节点的 CPU 或内存使用超过 90% 时清理该节点上的服务,你可以使用以下几种方法: 自定义脚本和 cron job:编写一个脚本监控节点的资源使用情况,并在超过阈值时触发清理操作。使用 DaemonSet 运行监控…...
JS如何把年月日转为时间戳
在JavaScript中,将年月日(通常表示为一个字符串或者分别的年、月、日数字)转换为时间戳(即Unix时间戳,是自1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不考虑闰秒)可以…...
【YOLOv5进阶】——引入注意力机制-以SE为例
声明:笔记是做项目时根据B站博主视频学习时自己编写,请勿随意转载! 一、站在巨人的肩膀上 SE模块即Squeeze-and-Excitation 模块,这是一种常用于卷积神经网络中的注意力机制!! 借鉴代码的代码链接如下&a…...
【C++题解】1456. 淘淘捡西瓜
问题:1456. 淘淘捡西瓜 类型:贪心 题目描述: 地上有一排西瓜,每个西瓜都有自己的重量。淘淘有一个包,包的容量是固定的,淘淘希望尽可能在包里装更多的西瓜(当然要装整个的,不能切开…...
用Python读取Word文件并提取标题
前言 在日常工作中,我们经常需要处理Word文档,特别是从中提取关键信息,如标题、段落等。今天,我们将利用Python来实现这一功能,并为大家提供一段完整的代码示例。 准备工作 首先,你需要安装python-docx库…...
Windows编程上
Windows编程[上] 一、Windows API1.控制台大小设置1.1 GetStdHandle1.2 SetConsoleWindowInfo1.3 SetConsoleScreenBufferSize1.4 SetConsoleTitle1.5 封装为Innks 2.控制台字体设置以及光标调整2.1 GetConsoleCursorInfo2.2 SetConsoleCursorPosition2.3 GetCurrentConsoleFon…...
BiTCN-Attention一键实现回归预测+8张图+特征可视化图!注意力全家桶再更新!
声明:文章是从本人公众号中复制而来,因此,想最新最快了解各类智能优化算法及其改进的朋友,可关注我的公众号:强盛机器学习,不定期会有很多免费代码分享~ 目录 原理简介 数据介绍 结果展示 全家桶代码目…...
zoom缩放问题(关于ElementPlus、Echarts、Vue3draggable等组件偏移问题)
做了一个项目下来,由于整体界面偏大,采取了缩放90%,导致很多组件出现偏移问题,以下我会把我遇到的各种组件偏移问题依次进行描述解答: ElementPlus选择器下拉偏移 <template><el-select :teleported"f…...
【后端面试题】【中间件】【NoSQL】MongoDB的配置服务器、复制机制、写入语义和面试准备
MongoDB的配置服务器 引入了分片机制之后,MongoDB启用了配置服务器(config server) 来存储元数据,这些元数据包括分片信息、权限控制信息,用来控制分布式锁。其中分片信息还会被负责执行查询mongos使用。 MongoDB的配置服务器有一个很大的优…...
视频监控汇聚平台LntonCVS视频监控业务平台具体有哪些功能?
LntonCVS视频监控平台是一款基于H5技术开发的专业安防视频监控产品,旨在为安防视频监控行业提供全面的解决方案。以下是平台的主要功能和特点: 1. 统一接入管理: - 支持国内外各种品牌、协议和设备类型的监控产品统一接入管理。 - 提供标准的…...
我不小心把生产的数据改错了!同事帮我用MySQL的BinLog挽回了罚款
之前在生产做修改数据的时候不小心改错了一行数据,本来以为会被通报批评,但是同事利用binlog日志查看到了之前的旧数据,并且帮我回滚了,学到了,所以写了一篇binlog的文章分享给大家。 MySQL的Binary Log(简…...
Windows系统安装NVM,实现Node.js多版本管理
目录 一、前言 二、NVM简介 三、准备工作 1、卸载Node 2、创建文件夹 四、下载NVM 五、安装NVM 六、使用NVM 1、NVM常用操作命令 2、查看NVM版本信息 3、查看Node.js版本列表; 4、下载指定版本Node.js 5、使用指定版本Node.js 6、查看已安装Node.js列…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
