C++为含数组成员的类实现<=>飞船运算符的编译报错问题
包含数组成员的类三路比较运算符修复方案
现有实现思路没有根本性偏差,核心目标是逐元素比较成员数组后聚合结果,但存在多处语法错误、API误用和逻辑疏漏,导致无法编译,也无法正确实现比较逻辑。
现有代码的具体问题
- 头文件与命名空间缺失:代码使用了
std::array、std::accumulate,但仅引入了<compare>头文件,缺少<array>和<numeric>;同时所有标准库组件都省略了std::命名空间前缀,会导致符号找不到。 std::strong_ordering无默认构造函数:该类型是三路比较的专用结果类型,没有公开默认构造函数,直接声明std::array<std::strong_ordering,4> cmps时,数组会尝试默认构造4个strong_ordering实例,触发编译错误。std::accumulate调用完全错误:- 第三个初始值参数误传了
std::equal(这是等价比较的函数标签,不是比较结果值),正确初始值应为std::strong_ordering::equal - 聚合逻辑错误:
std::strong_ordering不是布尔类型,不能直接用and逻辑运算,原lambda的返回逻辑完全不符合三路比较的聚合规则
- 第三个初始值参数误传了
- 成员函数缺少const限定:原
size()函数没有加const,无法在const成员函数(比如operator<=>本身是const限定的)或常对象上调用。
正确实现方式
绝大多数场景下,数组成员的比较逻辑和标准库容器一致,采用字典序逐元素比较:从第一个元素开始逐对比较,遇到第一对不相等的元素就返回对应比较结果,只有所有元素完全相等时才返回相等。这种逻辑std::array本身已经原生支持,最简单的实现直接默认生成运算符即可:
#include <compare> #include <array> class witharray { private: std::array<int,4> the_array; public: witharray( std::array<int,4> v ) : the_array(v) {} int size() const { return the_array.size(); } // 编译器自动按成员声明顺序生成三路比较逻辑,直接调用array的默认比较规则 auto operator<=>(const witharray&) const = default; // 显式生成相等比较逻辑,支持==、!=操作 bool operator==(const witharray&) const = default; };
如果需要手动实现比较逻辑(比如要加自定义校验、或者成员不是原生支持<=>的类型),直接短路遍历即可,不需要预先存储所有元素的比较结果,性能更高:
#include <compare> #include <array> class witharray { private: std::array<int,4> the_array; public: witharray( std::array<int,4> v ) : the_array(v) {} int size() const { return the_array.size(); } auto operator<=>(const witharray& other) const { for (int i = 0; i < the_array.size(); ++i) { // 遇到第一个不相等的元素直接返回结果,无需继续遍历 if (auto cmp = the_array[i] <=> other.the_array[i]; cmp != 0) { return cmp; } } return std::strong_ordering::equal; } bool operator==(const witharray& other) const { return the_array == other.the_array; } };
注:如果你确实需要“所有元素比较结果全为<才返回<、全为>才返回>”的特殊逻辑,这种规则不属于全序关系,无法用
std::strong_ordering表达,需要自行定义返回类型,绝大多数业务场景不需要这种逻辑。
内容的提问来源于stack exchange,提问作者Victor Eijkhout
相关产品推荐
相关产品推荐

