std::ranges::make_heap 使用std::ranges::less,它有一个约束:
与 std::less 不同,std::ranges::less 要求所有六个比较运算符 <、<=、>、>=、== 和 != 都有效(通过 totally_ordered_with 约束) .
您的类型S 没有相等运算符; spaceship 运算符仅提供其他比较运算符。*
要解决此问题,请为您的类型提供 operator==:
constexpr auto operator==(const S& s) const {
return i == s.i;
}
神栓链接:https://godbolt.org/z/cGfrxs
* operator<=> 出于性能原因并不暗示 operator==,因为 operator== 可以短路集合,而 operator<=> 不能。但是,从 https://en.cppreference.com/w/cpp/language/default_comparisons 中,我们看到默认的 operator<=> 也将隐式默认 operator==。
我是怎么想出来的?您的代码的错误消息包括以下内容(由我修剪和包装):
note: the expression 'is_invocable_v<_Fn, _Args ...>
[with _Fn = std::ranges::less&; _Args = {value_type&, value_type&}]'
evaluated to 'false'
338 | concept invocable = is_invocable_v<_Fn, _Args...>;
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
这意味着std::ranges::make_heap 发现它不能为我们的类型调用std::ranges::less。对向量的value_type 重复此错误消息调查std::ranges::less 会产生:
note: no operand of the disjunction is satisfied
123 | requires totally_ordered_with<_Tp, _Up>
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
124 | || __detail::__less_builtin_ptr_cmp<_Tp, _Up>
此时,编译器正在努力告诉我们我们不满意 totally_ordered_with,这意味着是时候查看概念文档和 std::ranges::less 的文档了。