稳定排序以及默认与自定义三向比较

问题描述 投票:0回答:1
为什么下面带有自定义三向比较运算符的代码无法编译?当用默认值替换自定义三向比较运算符时,它确实会编译(在下面的代码中注释掉)。我使用 GCC 13.2 和 Clang 18.1 对此进行了测试。

#include <vector> #include <algorithm> #include <compare> struct A { std::strong_ordering operator<=>(const A&) const { return std::strong_ordering::equivalent; }; // std::strong_ordering operator<=>(const A&) const = default; int x; }; int main () { std::vector<A> v = { {1}, {3}, {4}, {7}}; std::ranges::stable_sort(v); return 0; }
错误消息包括 

is_invocable_v<std::ranges::less &, A &, A &>' evaluated to false

,但是 
const bool x = A(1) < A(2)
 确实可以编译。请在此处查看详细的编译器错误:
https://gcc.godbolt.org/z/T5o7dG3Kq

c++ gcc c++20
1个回答
0
投票

std::ranges::stable_sort

 使用 
std::ranges::less
 的特化来比较对象。

[范围.cmp]#8:

约束:T 和 U 满足

totally_ordered_with

(参见

[概念.完全排序]

其中,需要

operator==

存在。虽然 
operator<=>
 隐式生成 
>=
<=
 运算符,

[类.比较]#4:

如果

member-specation 未显式声明任何名为 operator==

 的成员或友元,则为定义为默认 [...]
的每个三向比较运算符函数隐式声明一个
==
运算符函数

也就是说,只有默认的

operator<=>

才会隐式生成
operator==
,不符合要求
totally_ordered_with

声明一个

==

 运算符就足够了:

struct A { std::strong_ordering operator<=>(const A&) const { return std::strong_ordering::equivalent; }; + bool operator==(const A&) const { + return false; + } int x; };
    
© www.soinside.com 2019 - 2024. All rights reserved.