当前位置: 首页 > news >正文

聊聊C++20的三向比较运算符 `<=>`

C++20标准引入了许多新特性,其中之一是三向比较运算符 <=>,也被称为太空船运算符。这个新运算符为C++程序员提供了一种全新的比较对象的方式,它能有效简化比较逻辑,避免编写多个比较运算符重载的情况。

为什么需要三向比较运算符?

在C++20之前,如果要完整地定义一个类型的比较行为,你需要重载四个运算符:==!=<>,有时还包括 <=>=。这不仅使得代码冗长,而且增加了出错的可能性,因为需要确保所有这些运算符之间的逻辑一致性是一件不容易的事情。

三向比较运算符引入后,开发者就可以用单一的运算符表达相同的意图。这提高了代码的简洁性和可读性,并有助于减少错误。

三向比较运算符的工作原理

三向比较运算符通过比较两个对象,返回一个表示它们比较结果的值。这个值可以告诉我们两个对象是否相等、一个是否小于另一个,或者一个是否大于另一个。

在C++20中,这个运算符返回的不是简单的整数,而是std::strong_orderingstd::weak_orderingstd::partial_ordering中的一个值,这些都是定义在<compare>头文件中的新类型。

认识新的比较类别

运算符<=>返回的比较类别提供了不同级别的比较保证:

在C++20中引入了三向比较运算符<=>,也称为太空船运算符,它允许在单个操作中进行全面的比较。与这个运算符一起引入的还有几种新的比较类别,分别是std::strong_orderingstd::weak_orderingstd::partial_ordering。这些类别定义了比较的结果类型,并提供了不同的比较保证。

std::strong_ordering

std::strong_ordering是指两个值之间存在强序关系,即可以明确地比较它们的大小。它提供了最强的比较保证,即总是可以确定两个值是相等的、第一个值小于第二个值,还是第一个值大于第二个值。

使用std::strong_ordering的情况下,比较操作符(<=>)将返回std::strong_ordering::equalstd::strong_ordering::lessstd::strong_ordering::greater中的一个,分别代表相等、小于和大于。这允许我们对比较结果进行清晰的布尔测试。

例如,基本数据类型(如整型和浮点型)之间的比较通常使用std::strong_ordering

std::weak_ordering

std::weak_ordering提供了较弱的比较保证,它通常用于那些可以比较等价性,但不能总是完全确定排序关系的场合。例如,在某些情况下,两个不同的对象可能被视为等价的,尽管它们并不完全相等。

std::weak_ordering返回std::weak_ordering::equivalentstd::weak_ordering::lessstd::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::lessstd::partial_ordering::equivalentstd::partial_ordering::greaterstd::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++的发展趋势,提供了一种更为高效和直观的比较方法,也在语言层面上极大地简化了开发者的工作。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 大数据中的常见数据问题:独断脏
  • 网络基础:IS-IS协议
  • 【数据结构与算法】快速排序霍尔版
  • LabVIEW机器视觉系统中的图像畸变、校准和矫正
  • CentOS7安装部署Anaconda
  • 用 Echarts 画折线图
  • PYTHON自学笔记(一)vscode配置
  • 慧哥充电桩开源平台小程序、PC后、手机商户端历经2年的无数次迭代。
  • 通信协议_C#实现自定义ModbusRTU主站
  • ActiViz实战:vtkMath中的陷阱
  • centos7|操作系统|低版本的OpenSSH升级到最新版本OpenSSH-9.8.p1
  • 海外仓一件代发功能自动化:海外仓WMS系统配置方法
  • 人工智能、机器学习、神经网络、深度学习和卷积神经网络的概念和关系
  • 大数据面试题之数据库(1)
  • 2-5 softmax 回归的简洁实现
  • css的样式优先级
  • Go 语言编译器的 //go: 详解
  • Java 11 发布计划来了,已确定 3个 新特性!!
  • MySQL用户中的%到底包不包括localhost?
  • October CMS - 快速入门 9 Images And Galleries
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • react 代码优化(一) ——事件处理
  • SpiderData 2019年2月23日 DApp数据排行榜
  • TCP拥塞控制
  • 闭包--闭包作用之保存(一)
  • 前嗅ForeSpider教程:创建模板
  • 新手搭建网站的主要流程
  • 新海诚画集[秒速5センチメートル:樱花抄·春]
  • 支付宝花15年解决的这个问题,顶得上做出十个支付宝 ...
  • 智能情侣枕Pillow Talk,倾听彼此的心跳
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • ​html.parser --- 简单的 HTML 和 XHTML 解析器​
  • ‌内网穿透技术‌总结
  • # Python csv、xlsx、json、二进制(MP3) 文件读写基本使用
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (el-Transfer)操作(不使用 ts):Element-plus 中 Select 组件动态设置 options 值需求的解决过程
  • (Matalb分类预测)GA-BP遗传算法优化BP神经网络的多维分类预测
  • (Redis使用系列) Springboot 整合Redisson 实现分布式锁 七
  • (vue)el-checkbox 实现展示区分 label 和 value(展示值与选中获取值需不同)
  • (二)c52学习之旅-简单了解单片机
  • (附源码)基于SSM多源异构数据关联技术构建智能校园-计算机毕设 64366
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (一)SpringBoot3---尚硅谷总结
  • (原創) 如何安裝Linux版本的Quartus II? (SOC) (Quartus II) (Linux) (RedHat) (VirtualBox)
  • (原創) 如何刪除Windows Live Writer留在本機的文章? (Web) (Windows Live Writer)
  • (正则)提取页面里的img标签
  • .net core webapi Startup 注入ConfigurePrimaryHttpMessageHandler
  • .NET 设计模式初探
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • .NET文档生成工具ADB使用图文教程
  • //usr/lib/libgdal.so.20:对‘sqlite3_column_table_name’未定义的引用
  • ::before和::after 常见的用法
  • @JsonSerialize注解的使用
  • @RequestParam @RequestBody @PathVariable 等参数绑定注解详解