自定义operator<=>为何导致std::three_way_comparable返回false?
自定义operator<=>导致std::three_way_comparable返回false的原因及修复
问题出在std::three_way_comparable的底层要求上:它不仅要求类型定义了operator<=>,还要求类型满足std::equality_comparable(即拥有合法的相等比较运算符operator==)。
- 使用默认生成的
operator<=>(const UDTC&, const UDTC&) = default;时,编译器会自动合成对应的operator==,因此UDTC满足所有特性要求,检测返回true。 - 自定义实现
operator<=>时,编译器不会自动生成operator==,此时UDTC缺少相等比较运算符,不满足std::equality_comparable,最终导致std::three_way_comparable检测失败。
修复代码
只需要给UDTC补充显式的operator==即可,两种方式都可以:
方式一:手动实现operator==
#include <cstdio> #include <compare> using namespace std; struct UDTC { int i_; UDTC(int i) : i_(i) {} friend std::strong_ordering operator<=>(const UDTC &lhs, const UDTC &rhs) { return lhs.i_ <=> rhs.i_; } // 补充相等比较运算符 friend bool operator==(const UDTC& lhs, const UDTC& rhs) { return lhs.i_ == rhs.i_; } }; int main(void) { if constexpr (std::three_way_comparable<UDTC>) { fprintf(stderr, "UDTC is three_way_comparable\n"); } else { fprintf(stderr, "UDTC is NOT three_way_comparable\n"); } }
方式二:默认生成operator==(更简洁)
#include <cstdio> #include <compare> using namespace std; struct UDTC { int i_; UDTC(int i) : i_(i) {} friend std::strong_ordering operator<=>(const UDTC &lhs, const UDTC &rhs) { return lhs.i_ <=> rhs.i_; } // 默认生成相等比较运算符 friend bool operator==(const UDTC&, const UDTC&) = default; }; int main(void) { if constexpr (std::three_way_comparable<UDTC>) { fprintf(stderr, "UDTC is three_way_comparable\n"); } else { fprintf(stderr, "UDTC is NOT three_way_comparable\n"); } }
补充后,std::three_way_comparable<UDTC>会返回true,和默认生成<=>的效果一致。
内容的提问来源于stack exchange,提问作者DRH
相关产品推荐
相关产品推荐

