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::isnan

struct 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";
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黑不溜秋的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值