如何在没有宇宙飞船比较运算符的情况下满足自定义类型的 totally_ordered (ranges::is_sorted, ranges::sort)

How to satisfy totally_ordered for a custom type without spaceship comparison operator (ranges::is_sorted, ranges::sort)

考虑以下代码:

#include <vector>
#include <algorithm>
#include <ranges>
#include <cassert>

// The type is defined in legacy code and we can not change it
struct A
{
   int a;
};

bool operator <(const A &a1, const A &a2)
{
   return a1.a < a2.a;
}

int main()
{
   assert(A {} < A{}); // OK
   std::vector<A> c;
   assert(std::ranges::is_sorted(c)); // compilation error
}

可以通过将“宇宙飞船”比较运算符添加到 A:

来修复代码
auto operator<=>(const A &) const = default;

但是,在 class 之外定义它适用于第一个 assert,但不适用于第二个:

auto operator <=>(const A &a1, const A &a2) { return a1.a <=> a2.a; }

是否可以在不修改A的情况下满足ranges::less的要求?

您需要 provide an == 以及 <=>std::ranges::less不仅需要std::totally_ordered,还需要std::strict_weak_order,所以还需要==。除非 defaulted,<=> 不会合成 ==

#include <vector>
#include <algorithm>
#include <ranges>
#include <cassert>

// The type is defined in legacy code and we can not change it
struct A
{
   int a;
};

auto operator <=>(const A &a1, const A &a2) { return a1.a <=> a2.a; }
auto operator ==(const A &a1, const A &a2) { return a1.a == a2.a; }

int main()
{
   assert(A {} < A{}); // Comparison exists
   std::vector<A> c;
   assert(std::ranges::is_sorted(c)); // Comparison exists
}