[英]what are the constraints for std::ranges::make_heap?
The following code works well with gcc:以下代码适用于 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());
But when I switch to C++20's range algorithm:但是当我切换到 C++20 的范围算法时:
std::ranges::make_heap(v);
I got this compiler error:我收到此编译器错误:
source>:14:27: error: no match for call to '(const std::ranges::__make_heap_fn) (std::vector<S>&)'
14 | std::ranges::make_heap(v);
|
^
It seems struct S
doesn't satisfy the requirements of the ranges::make_heap
, but I don't know what exactly it is, can someone help?似乎struct S
不满足ranges::make_heap
的要求,但我不知道它到底是什么,有人可以帮忙吗?
std::ranges::make_heap
uses std::ranges::less
, which has a constraint: std::ranges::make_heap
使用std::ranges::less
,它有一个约束:
Unlike
std::less
,std::ranges::less
requires all six comparison operators<
,<=
,>
,>=
,==
and!=
to be valid (via thetotally_ordered_with
constraint).与std::less
不同,std::ranges::less
要求所有六个比较运算符<
、<=
、>
、>=
、==
和!=
都有效(通过totally_ordered_with
约束)。
Your type S
does not have an equality operator;您的类型S
没有相等运算符; the spaceship operator only provides the other comparison operators.* spaceship 运算符仅提供其他比较运算符。*
To fix this, provide an operator==
for your type:要解决此问题,请为您的类型提供operator==
:
constexpr auto operator==(const S& s) const {
return i == s.i;
}
Godbolt Link: https://godbolt.org/z/cGfrxs Godbolt 链接: https ://godbolt.org/z/cGfrxs
* operator<=>
does not imply operator==
for performance reasons, as operator==
can short circuit over collections whereas operator<=>
cannot. * operator<=>
不暗示operator==
出于性能原因,因为operator==
可以使集合短路,而operator<=>
不能。 However, from https://en.cppreference.com/w/cpp/language/default_comparisons , we see that a defaulted operator<=>
will also implicitly default an operator==
.但是,从https://en.cppreference.com/w/cpp/language/default_comparisons ,我们看到默认operator<=>
也将隐式默认operator==
。
How did I figure this out?我是怎么想出来的? The error message for your code includes the following (trimmed and word wrapped by me):您的代码的错误消息包括以下内容(由我修剪和包装):
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...>; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This means that std::ranges::make_heap
finds that it can't call std::ranges::less
for our type.这意味着std::ranges::make_heap
发现它不能为我们的类型调用std::ranges::less
。 Repeating this error message investigation for std::ranges::less
on the value_type
of the vector yields:对向量的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>
At this point, the compiler is trying hard to tell us that we aren't satisfying totally_ordered_with
, which means that it's time to hit the documentation for the concept and for std::ranges::less
.在这一点上,编译器正在努力告诉我们我们没有满足totally_ordered_with
,这意味着是时候查看概念和std::ranges::less
的文档了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.