我有一个案例,当结构类型需要非默认时operator<=>
- 在定义对象顺序时并非所有字段都很重要。
struct A
{
int a;
int b; // not important when ordering
int c;
constexpr std::strong_ordering operator<=>(const A& rhs) const
{
if (const auto res = a<=>rhs.a; res != 0) return res;
return c<=>rhs.c;
}
};
令我惊讶的是,我不能使用这种类型的容器作为参数std::ranges::sort
:
std::array<A, 100> aa{};
std::ranges::sort(aa);
我在最新的 gcc (14) 和 clang (19) 上检查了它,它基本上声称范围不可排序,因为std::invocable_v<std::ranges::less&, A&, A&>
事实并非如此。请参阅godbold 链接
更多观察:
- 它与 std::sort(
std::sort(aa.begin(), aa.end());
)一起使用 - 添加非默认时有效
operator==
- 并且它与默认值 (
=default
)一起使用operator<=>
这是编译器错误、C++ 标准错误还是某些奇怪的 C++ 规则在这里起作用,并且应该是这样的?如果最后一个选项是正确的 - 您能为这种行为提供理由吗?
更新:
从评论来看,似乎std::ranges::less{}(A{}, A{})
不仅需要operator<
(派生自operator<=>
),而且operator==
不能从非默认派生而来,operator<=>
因此出现错误。
但仍然存在一个问题——为什么std::ranges::less
需要operator==
?
评论中的更好的例子:链接