如何在没有宇宙飞船比较运算符的情况下满足自定义类型的 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
,所以还需要==
。除非 default
ed,<=>
不会合成 ==
。
#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
}
考虑以下代码:
#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
,所以还需要==
。除非 default
ed,<=>
不会合成 ==
。
#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
}