C++20特性之三路比较操作符

内容纲要

在C++20中,引入了一个新的运算符,称为“三路比较操作符”或“太空船操作符”,其符号为 <=>。这个运算符是C++20中的一个重要特性,提供了一种简化两个对象比较的方法。

三路比较操作符返回一个标准库类型std::strong_ordering(默认类型)、std::weak_ordering或std::partial_ordering的实例,这取决于参与比较的对象类型的属性。这个运算符基本上可以告诉你两个值是相等的、第一个值小于第二个值,还是第一个值大于第二个值。

这个操作符的行为类似于以下的组合:

  • 如果a < b,则返回一个表示"小于"的值。
  • 如果a > b,则返回一个表示"大于"的值。
  • 如果a == b,则返回一个表示"等于"的值。

比如:

#include <compare>

auto result = a <=> b;

if (result < 0) {
    // a 小于 b
    std::cout << "a < b" <<std::endl;
} else if (result > 0) {
    // a 大于 b
        std::cout << "a > b" <<std::endl;
} else {
    // a 等于 b
        std::cout << "a = b" <<std::endl;
}

这种新的比较方法简化了类的排序和比较逻辑的实现,因为你只需要定义一种比较方式,而不是像以前那样分别定义 <、> 和 ==。

让我们以如下例子对比传统的比较方法和C++20中引入的三路比较操作符(太空船操作符):

传统比较方法

在C++20之前,如果你想要在自定义类型上实现比较操作(如<, >, ==),你需要分别为每个操作符提供实现。例如,对于一个简单的Point类,它可能看起来是这样的:

class Point {
public:
    int x, y;

    bool operator==(const Point& other) const {
        return x == other.x && y == other.y;
    }

    bool operator<(const Point& other) const {
        return x < other.x || (x == other.x && y < other.y);
    }

    bool operator>(const Point& other) const {
        return other < *this;
    }

    // 可能还需要其他比较操作符...
};

使用三路比较操作符

C++20引入了三路比较操作符<=>,它允许你通过单一的函数实现所有标准比较。使用这个操作符,上面的Point类可以这样简化:

#include <compare>

class Point {
public: 
    int x, y; //编译器按照字段声明的顺序进行比较,auto推导为 strong_ordering

    auto operator<=>(const Point& other) const = default; 
};

在这个例子中,我们只定义了一个操作符<=>,编译器将为我们生成所有必要的比较操作符(<, <=, >, >=, ==, !=)。我们使用= default来让编译器自动生成标准的比较逻辑。

可以从 cpp insight 看看编译器干了啥:

#include <compare>

class Point
{

  public: 
  int x;
  int y;
  inline constexpr std::strong_ordering operator<=>(const Point & other) const /* noexcept */ = default;
  inline constexpr bool operator==(const Point & other) const /* noexcept */ = default;
};

对比

  1. 简洁性:使用三路比较操作符可以显著减少代码量。你只需要一个操作符定义,而不是为每个比较操作写单独的函数。

  2. 错误减少:当你手动实现多个比较操作符时,可能会引入错误或不一致。使用三路比较操作符可以降低这种风险。

  3. 维护性:如果比较逻辑改变,使用三路比较操作符的代码只需在一个地方进行修改,而传统方法可能需要修改多处。

  4. 性能:在某些情况下,使用三路比较操作符可能提供更优的性能,因为编译器可以更有效地优化比较操作。

总的来说,三路比较操作符是C++20中一个强大且有用的特性,它简化了比较逻辑的实现,使代码更加清晰和易于维护。

打赏作者