首页 > 编程语言 >聊聊C++20的三向比较运算符 `<=>`

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

时间:2024-07-03 11:28:24浏览次数:22  
标签:std 20 ordering weak C++ 运算符 partial 比较

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

标签:std,20,ordering,weak,C++,运算符,partial,比较
From: https://blog.csdn.net/hebhljdx/article/details/140120245

相关文章

  • C++课程设计--学生宿舍管理系统
    需求分析        系统主要使用类链表,将链表的知识得到充分的使用;还是用到了函数重载。 类定义    主要包括学生类、宿舍类、报修类以及访客类。由于博主时间问题并没有写到访客类的代码,但是思路是一样的。学生类    数据成员:学生学号、姓名、性......
  • 2024UIUCTF - OSINT - Night
    2024UIUCTF-OSINT-Night题目描述Author:CBCicadaThatwasquiteaprettynightview,canyoufindwhereItookit?Flagformat:uiuctf{streetname,cityname}Example:uiuctf{EastGreenStreet,Champaign}Somewordsareblurredouttomakethechallengeh......
  • 丝滑解决ImportError: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_
    基础环境:MacOSm1、python=3.9前情提要:在Anaconda终端运行代码的时候,显示报错:importError:/usr/lib/x86_64-linux-gnu/libstdc++.so.6:version`GLIBCXX_3.4.29'notfound1问题分析:根据提示是/usr/lib/x86_64-linux-gnu/路径下的libstdc++.so.6缺少版本GLIBCXX_3.4.29解......
  • python+中医病案管理系统设计与实现-计算机毕业设计源码131320
    摘 要随着互联网时代的到来,同时计算机网络技术高速发展,网络管理运用也变得越来越广泛。因此,建立一个B/S结构的中医病案管理系统,会使;中医病案管理系统的管理工作系统化、规范化,也会提高平台形象,提高管理效率。本系统是针对目前中医病案管理系统的实际需求,从实际工作出发,对过......
  • springboot+手机商城网站-计算机毕业设计源码201029
    摘 要在信息飞速发展的今天,网络已成为人们重要的信息交流平台。手机店每天都有大量的手机商品需要通过网络发布,为此,本人开发了一个基于springboot手机商城网站。本系统采用跨平台的JAVA语言开发,利用springboot框架进行逻辑控制,MySQL数据库存储数据,最后Tomcat服务器完成发布......
  • 2024爆火全网的LLM大语言模型黑书!入门大模型大家全都在学~(附pdf)
    今天给大家推荐一本4月份才新出的大型语言模型(LLM)的权威教程《基于GPT-3、ChatGPT、GPT-4等Transformer架构的自然语言处理》!Google工程总监AntonioGulli作序,一堆大佬推荐!这含金量不用多说,不多bb开始介绍!本教程内容主要内容•了解用于解决复杂语言问题的新技术•将GP......
  • C++学习1 “&”符号的用法
    “单纯来源于CHATGPT”一在C++中,&符号具有多重用途,主要包括以下几种情况:1.地址运算符当&用于变量前面时,它作为一种一元运算符,用来获取该变量在内存中的地址。例如:inta=5;int*p=&a;//p存储a的内存地址这里&a表示变量a的地址。2.引用声明在类型声明......
  • 【2024-06-30】连岳摘抄
    23:59每一个独立的个体内在都带着很细微的但是待释放的强大的爱的发电机。我们得承认爱能降服一切,爱超越每一个存在和任何存在,因为爱就是生命的精髓。                                       ......
  • 【2024-06-29】连岳摘抄
    23:59不管什么人,你若想深入了解,就得逐步接近,慎重地对待他,免得看错了人,形成偏见,事后想要纠正、抹掉,那就非常困难了。                                                 —......
  • 2024年《地政》第十一章整理学习黑板报
      ......