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

C++ 语言特性22 - 三向比较

一:概述

        C++20 引入了“三向比较运算符”(<=>),也称为“spaceship 运算符”,用来简化比较操作。这个运算符可以同时处理小于、大于和等于的比较,提供一个统一的接口来完成各种比较操作。

        1. 基本语法

auto result = lhs <=> rhs;/*
如果 lhs 小于 rhs,则返回负值(如 std::strong_ordering::less)。
如果 lhs 等于 rhs,则返回零值(如 std::strong_ordering::equal)。
如果 lhs 大于 rhs,则返回正值(如 std::strong_ordering::greater)
*/

         2. 返回结果

   三向比较运算符 <=> 生成一个比较结果对象,可以是以下三种类型之一:

  • std::strong_ordering
  • std::weak_ordering
  • std::partial_ordering

        它将比较结果封装为一个状态,可以是小于、等于或大于,简化了需要手动编写的多个比较运算符的实现。

        3. 三种返回结果类型的比较

  • std::strong_ordering

    • 强排序,严格遵循“弱序关系”,即如果 a == b,那么它们在其他比较中也应视为相等。
    • 默认适用于大多数内置类型,如 intdouble 等。
#include <compare>
#include <iostream>struct Point {int x, y;// 使用强排序std::strong_ordering operator<=>(const Point&) const = default;
};int main() {Point p1{1, 2};Point p2{1, 2};if (p1 == p2) {std::cout << "p1 is equal to p2\n";}
}
  • std::weak_ordering

    • 弱排序允许某些比较操作认为相等,但不一定意味着所有方面都相等。
    • 例如,浮点数中的 -0.00.0 被认为是相等的,尽管它们的二进制表示不同。
#include <compare>
#include <iostream>struct WeakFloat {float value;std::weak_ordering operator<=>(const WeakFloat& other) const {if (value == other.value) {return std::weak_ordering::equivalent; // 等价但不完全相等}return value <=> other.value;}
};int main() {WeakFloat f1{0.0f};WeakFloat f2{-0.0f};if (f1 == f2) {std::cout << "f1 is equivalent to f2\n";}
}
  • std::partial_ordering

    • 部分排序适用于无法定义严格顺序的情况,比如浮点数中的 NaN 值(非数字),NaN 与任何数比较的结果都是无序的。
#include <compare>
#include <iostream>
#include <cmath>  // 为了使用 std::isnanstruct PartialFloat {float value;std::partial_ordering operator<=>(const PartialFloat& other) const {if (std::isnan(value) || std::isnan(other.value)) {return std::partial_ordering::unordered; // 无法比较}return value <=> other.value;}
};int main() {PartialFloat f1{NAN};PartialFloat f2{1.0};if ((f1 <=> f2) == std::partial_ordering::unordered) {std::cout << "f1 and f2 are unordered\n";}
}

 二:三向比较与布尔值

        三向比较运算符的返回值可以用于布尔逻辑中,配合 ==, !=, <, <=, >, >= 使用。C++20 自动为你定义这些运算符,具体实现的逻辑依赖于三向比较的返回类型。

#include <compare>
#include <iostream>int main() {int a = 5, b = 10;// 使用三向比较运算符的结果进行布尔判断if ((a <=> b) < 0) {std::cout << "a is less than b\n";}
}//在这个示例中,a <=> b 的结果为 std::strong_ordering::less,因此条件 (a <=> b) < 0 为真,表示 a < b。

 三:自定义三向比较

        虽然 default 的三向比较运算符适合大多数情况,但你也可以自定义它来实现复杂的比较逻辑。

#include <compare>
#include <iostream>class Point {
public:int x, y;// 自定义三向比较运算符std::strong_ordering operator<=>(const Point& other) const {if (auto cmp = x <=> other.x; cmp != 0) {return cmp;}return y <=> other.y;}
};int main() {Point p1{1, 2};Point p2{1, 3};if (p1 < p2) std::cout << "p1 is less than p2\n";if (p1 == p2) std::cout << "p1 is equal to p2\n";if (p1 > p2) std::cout << "p1 is greater than p2\n";
}


http://www.mrgr.cn/news/42974.html

相关文章:

  • Java后端开发中的数据保护:如何实现全面的数据加密
  • 计算机组成原理之无符号整数的表示和运算
  • C++ 语言特性21 - 别名模板
  • 【C++差分数组】2381. 字母移位 II|1793
  • 探索Python的魔法:标准库与第三方库的奇妙世界
  • Chat登录时出现SSO信息出错的解决方法
  • 随时随地,轻松翻译:英汉互译软件的便捷之旅
  • HTML ASCII:Web 开发中的字符编码基础
  • 业务封装与映射 -- 编码方式(QPSK、DQPSK、QAM)
  • 腾讯自研Git客户端,助力每个人都可以轻松使用Git
  • Bootstrap 5 网格系统
  • 15分钟学 Python 第37天 :Python 爬虫入门(三)
  • 污水排放口细粒度检测数据集,污-水排放口的类型包括10类目标,10000余张图像,yolo格式目标检测,9GB数据量。
  • Java中的数据格式转换:JSON、XML与Protobuf的应用与选择
  • 用Python实现运筹学——Day 12: 线性规划在物流优化中的应用
  • 解决:__init__() got an unexpected keyword argument ‘logging_dir‘
  • 方法重写与多态
  • spring boot jar 分离自动部署脚本
  • 【Python】pyenv:管理多版本 Python 环境的利器
  • NumPy 第四课 -- 数据类型