指向自定义比较器对象的指针集合



我想重载类Node的左操作符(<)。注意,元素不是类对象,而是指向它们的指针。请参阅主类中定义的set<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;
}
bool operator<(const Node& node) const {
return this->x < node.x;
}
};
int main() {
set<Node*> 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;
return 0;
}

问题是,默认情况下std::set使用std::less进行比较。请在这里阅读。

std::less能够比较Node*。您的比较函数将永远不会被调用。代替。所有内容都将根据指针值(对于您的随机值)排序。这是new返回的值。

你需要的是一个Functor,以以下形式比较你的值:

bool operator ()(const Node* n1, const Node* n2) const {
return (n1->x == n2->x) ? n1->y < n2->y : n1->x < n2->x;
}

你可以使用一个单独的函子,一个Lambda,一个自由函数,或者,你可以把这个函数添加到你的Node中,这样,使它成为Functor。然后将其作为第二个参数添加到std::set定义中。

所以,你有很多种方法。让我以最后一个选项为例。

请见:

#include <iostream>
#include <set>
using namespace std;
class Node {
public:
int x{}, y{};
Node* prev{}, * next{};
Node() {};
Node(int x, int y) {
this->x = x; this->y = y;
this->prev = this->next = nullptr;
}

bool operator ()(const Node* n1, const Node* n2) const {
return (n1->x == n2->x) ? n1->y < n2->y : n1->x < n2->x;
}
};
int main() {
set<Node*, Node> 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;
return 0;
}