康桓瑋*_*康桓瑋 5 c++ c++20 std-ranges
以下代码适用于 gcc:
struct S {
int i, j;
auto operator<(const S& s) const {
return i < s.i;
};
};
std::vector<S> v;
std::make_heap(v.begin(), v.end());
Run Code Online (Sandbox Code Playgroud)
但是当我切换到 C++20 的范围算法时:
std::ranges::make_heap(v);
Run Code Online (Sandbox Code Playgroud)
source>:14:27: error: no match for call to '(const std::ranges::__make_heap_fn) (std::vector<S>&)'
14 | std::ranges::make_heap(v);
|
^
Run Code Online (Sandbox Code Playgroud)
似乎struct S不满足 的要求ranges::make_heap,但我不知道它到底是什么,有人可以帮忙吗?
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;
}
Run Code Online (Sandbox Code Playgroud)
Godbolt 链接:https ://godbolt.org/z/cGfrxs
*operator<=>并不意味着operator==出于性能原因,因为operator==可以在集合上短路而operator<=>不能。但是,从https://en.cppreference.com/w/cpp/language/default_comparisons,我们看到默认值operator<=>也会隐式默认operator==.
我是怎么想出来的?您的代码的错误消息包括以下内容(由我修剪和包装):
Run Code Online (Sandbox Code Playgroud)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我们的类型。重复此错误信息的调查std::ranges::less上value_type的载体产生的:
Run Code Online (Sandbox Code Playgroud)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。
| 归档时间: |
|
| 查看次数: |
112 次 |
| 最近记录: |