如何正确重载C++的<运算符?std::set<std::pair<int,NodeA>>报错排查
解决
std::set<std::pair<int,NodeA>>的operator<编译错误问题 你碰到的这个编译报错,核心问题出在NodeA类的<运算符重载上,咱们一步步理清楚:
错误根源
编译器提示找不到const NodeA和const NodeA之间的operator<,原因很简单:
std::set为了保证内部元素的有序性,会把存储的元素当作const对象处理- 你当前定义的
operator<不是const成员函数,const对象无法调用非const成员函数,这就导致了匹配失败
修复方案
把NodeA的<运算符重载改成const成员函数,另外还要完善比较逻辑——你现在只比较了posX,如果两个NodeA的posX相等,会被set判定为相同元素,导致无法插入,所以最好补充posY的比较:
class NodeA { //... bool operator<(const NodeA& a) const { // 这里必须加const if (posX < a.posX) { return true; } else if (posX == a.posX) { // 补充posY的比较,避免posX相同时的判断错误 return posY < a.posY; } else { return false; } } //... };
额外补充
std::pair的比较逻辑是先比第一个元素(你的代码里是int类型的i + j * x),只有当第一个元素相等时,才会比较第二个元素(NodeA对象)。所以要注意第一个int值是否可能重复,如果重复,就完全依赖NodeA的比较逻辑来区分元素。- 如果你不想修改
NodeA类,也可以自定义比较器,在声明std::set时指定:
struct NodeACmp { bool operator()(const std::pair<int, NodeA>& lhs, const std::pair<int, NodeA>& rhs) const { if (lhs.first != rhs.first) { return lhs.first < rhs.first; } // 这里实现NodeA的比较逻辑,无需修改NodeA类 if (lhs.second.posX < rhs.second.posX) { return true; } else if (lhs.second.posX == rhs.second.posX) { return lhs.second.posY < rhs.second.posY; } return false; } }; // 声明set时指定自定义比较器 std::set<std::pair<int, NodeA>, NodeACmp> nodi;
内容的提问来源于stack exchange,提问作者vrige
相关产品推荐
相关产品推荐

