如何为结构体定义operator<运算符?附相关结构体代码
如何为自定义结构体定义
operator<以适配std::set 首先,因为你在CICLO里使用了std::set<ARCO_TEMPO>,而std::set是有序关联容器,要求元素类型必须支持严格弱序比较——也就是必须定义operator<运算符。下面我们一步步来实现:
1. 先为Arco结构体定义operator<
ARCO_TEMPO包含Arco类型的成员,所以我们需要先让Arco支持比较。通常我们会按成员的优先级依次比较,这里可以先比i,i相等再比j。
简洁写法(推荐)
利用std::tie可以快速生成一个能按顺序比较成员的tuple,代码更简洁且不易出错:
#include <tuple> // 需要包含这个头文件 struct Arco { int i, j; Arco () {}; Arco (const Arco& obj): i(obj.i), j(obj.j) {}; Arco(int _i, int _j) : i(_i), j(_j) {} // 定义const版本的operator<,因为set的元素是const的 bool operator<(const Arco& other) const { return std::tie(i, j) < std::tie(other.i, other.j); } };
手动实现写法
如果你想更直观地控制比较逻辑,也可以手动写分支:
struct Arco { // ... 其他成员和构造函数 ... bool operator<(const Arco& other) const { if (i != other.i) { return i < other.i; } // i相等时比较j return j < other.j; } };
2. 为ARCO_TEMPO结构体定义operator<
同样按照成员的优先级来,比如先比较Arco成员a,再比较slotTimeU,最后比较slotTimeV:
简洁写法(推荐)
struct ARCO_TEMPO { Arco a; int slotTimeU; int slotTimeV; ARCO_TEMPO () {}; ARCO_TEMPO (const ARCO_TEMPO& obj): a(obj.a), slotTimeU(obj.slotTimeU), slotTimeV(obj.slotTimeV) {}; ARCO_TEMPO (Arco _a, int _slotTimeU, int _slotTimeV) : a(_a), slotTimeU(_slotTimeU), slotTimeV(_slotTimeV) {} bool operator<(const ARCO_TEMPO& other) const { return std::tie(a, slotTimeU, slotTimeV) < std::tie(other.a, other.slotTimeU, other.slotTimeV); } };
手动实现写法
struct ARCO_TEMPO { // ... 其他成员和构造函数 ... bool operator<(const ARCO_TEMPO& other) const { // 先比较Arco成员a if (a < other.a) { return true; } if (other.a < a) { return false; } // a相等时比较slotTimeU if (slotTimeU != other.slotTimeU) { return slotTimeU < other.slotTimeU; } // slotTimeU相等时比较slotTimeV return slotTimeV < other.slotTimeV; } };
关键注意事项
- 必须定义const版本的
operator<:因为std::set中的元素是不可修改的(const),所以调用的比较运算符必须是const成员函数,否则会编译报错。 - 严格弱序规则:你的
operator<必须满足严格弱序——简单来说就是:- 不能有
x < x成立(反自反性) - 如果
x < y成立,那么y < x一定不成立(非对称性) - 如果
x < y且y < z,那么x < z成立(传递性)
上面的两种写法都天然满足这些规则。
- 不能有
关于未完成的CICLO结构体
如果之后你需要让CICLO也支持比较(比如放进std::set或者用std::sort排序),可以按照同样的逻辑,根据CICLO的成员优先级来定义operator<。比如如果主要比较arco_tempo_order,可以直接比较这个std::set(因为std::set本身已经支持operator<)。
内容的提问来源于stack exchange,提问作者rbl
相关产品推荐
相关产品推荐

