重载Node类<运算符无效:set<Node*>无法按自定义规则排序求助
解决set<Node*>自定义排序失效问题
问题根源
你重载的Node::operator<是用于Node对象之间的比较,但std::set<Node*>默认使用std::less<Node*>作为比较器,它直接比较的是指针的内存地址,而非指针指向的Node对象内容。所以不管怎么重载Node类的<运算符,都不会被set调用,最终排序结果是按指针地址随机排列。
解决方案:给set指定自定义比较器
需要为set提供一个能比较两个Node指针指向对象的比较规则,具体有两种常用方式:
方式1:使用结构体作为比较器
定义一个重载了operator()的结构体,专门用于比较Node指针:
#include <iostream> #include <set> using namespace std; class Node { public: int x, y; Node *prev, *next; Node(int x, int y) { this->x = x; this->y = y; this->prev = this->next = nullptr; } }; // 自定义比较器:按Node的x值升序排序 struct CompareNode { bool operator()(const Node* a, const Node* b) const { // 若存在插入nullptr的场景,需额外处理,比如: // if (!a) return !b; // if (!b) return false; return a->x < b->x; } }; int main() { // 声明set时指定自定义比较器 set<Node*, CompareNode> S; S.insert(new Node(2, 4)); S.insert(new Node(3, 2)); S.insert(new Node(1, 4)); S.insert(new Node(5, 1)); S.insert(new Node(4, 3)); for (auto itr : S) cout << itr->x << endl; // 释放内存,避免内存泄漏 for (auto node : S) delete node; return 0; }
方式2:使用lambda表达式(C++11及以上)
如果不想定义单独的结构体,也可以用lambda作为比较器,但需要借助decltype来推导类型:
int main() { auto compare = [](const Node* a, const Node* b) { return a->x < b->x; }; set<Node*, decltype(compare)> S(compare); // 后续插入和遍历逻辑同上 }
注意事项
- 确保传入set的指针都是有效指针,避免空指针解引用。如果需要支持nullptr,要在比较器中添加判断逻辑。
- 原来的
Node::operator<仅在直接比较Node对象(如Node a(1,2); Node b(3,4); if(a < b))时生效,和set存储指针的场景无关。
内容的提问来源于stack exchange,提问作者Milind Prajapat
相关产品推荐
相关产品推荐

