首次使用std::weak_ordering(飞船运算符)的代码是否可行?
问题解答
1. 当前代码无法正常工作
你直接返回is_same_age的布尔值是错误的——飞船运算符operator<=>的返回值必须是比较类别类型(比如std::weak_ordering、std::partial_ordering),不能直接返回bool,编译器会因类型不匹配直接报错。
2. 正确的返回逻辑
要实现“所有属性全相等才判定为相等”的需求,逻辑应该是:
- 按顺序比较
name、breed、color:只要某一个属性与另一个对象的对应属性不等,就直接返回该属性的operator<=>结果(std::weak_ordering类型)。 - 如果前三个属性都相等,再处理年龄的比较:由于
double用<=>返回的是std::partial_ordering,更合理的做法是将整个operator<=>的返回类型统一为std::partial_ordering,避免类型兼容问题。
修正示例代码
#include <compare> #include <string> struct Dog { std::string name; std::string breed; std::string color; double age; bool is_same_age(const Dog& other) const { // 可根据需求替换为带epsilon的浮点数相等判断 return age == other.age; } // 用partial_ordering作为返回类型,适配double的部分有序特性 std::partial_ordering operator<=>(const Dog& other) const { if (auto cmp = name <=> other.name; cmp != 0) { return cmp; } if (auto cmp = breed <=> other.breed; cmp != 0) { return cmp; } if (auto cmp = color <=> other.color; cmp != 0) { return cmp; } // 处理年龄:自定义相等判断后转换为partial_ordering if (is_same_age(other)) { return std::partial_ordering::equivalent; } // 年龄不等时直接返回浮点数比较结果 return age <=> other.age; } // 借助<=>自动生成符合需求的==运算符 bool operator==(const Dog& other) const = default; };
3. 关键注意点
- 若坚持使用
std::weak_ordering作为返回类型,必须先确保年龄比较不会出现unordered(如排除NaN),再手动将partial_ordering的结果转换为weak_ordering,但这种做法违背了浮点数的部分有序特性,不推荐。 - 默认生成的
operator==会自动调用operator<=>并判断是否等价,刚好满足“所有属性全相等才返回true”的需求。
内容的提问来源于stack exchange,提问作者Cevapi Man69
相关产品推荐
相关产品推荐

