下面的代码调用运算符<=>两次,参数颠倒。但是为什么呢?
GCC 10.2和clang 12似乎都在使用libstdc++-10,它确实提供了运算符<=>,所以看起来并不是缺少标准库支持的情况,我的代码一定是不正确的。如何修复它?
#include <tuple>
#include <compare>
#include <iostream>
struct X {
int i;
auto operator <=>(X const& other) const {
std::cout << this << " <=> " << &other << std::endl;
return i <=> other.i;
}
};
int main() {
std::tuple{X{42}} <=> std::tuple{X{42}};
}发布于 2021-02-13 01:10:14
简而言之:您需要为X定义operator==。
std::tuple通过合成的三向比较来比较元素,仅当类型满足std::three_way_comparable_with<T,U>时才使用<=>。归根结底,这需要std::three_way_comparable,它需要一个描述性的weakly-equality-comparable-with概念。正如您可能猜到的,这需要==是有效的。
修复方法是一行代码:
bool operator==(X const& other) const = default;现在为什么需要==,而<=>似乎在这里自己完成了这项工作?我只能推测,但这可能是因为概念比我们过去只需要operator<的概念更“完整”。如果一个类型可以与<=>相媲美,那么它实际上也应该支持相等。
至于为什么<=>本身不涵盖==,除非是缺省的,这是因为等价性可能会短路的类(如向量和字符串)以及任何包含此类类型的类的性能陷阱。不会给出相等比较每个元素而不是短路的指示,所以<=>不会处理相等,除非它可以保证您将避免这种陷阱(通过缺省的<=>)。
https://stackoverflow.com/questions/66175605
复制相似问题