c++ 指向具有自定义比较器的对象的指针集

kh212irz  于 2023-01-22  发布在  其他
关注(0)|答案(1)|浏览(171)

我想为类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;
}
oxcyiej7

oxcyiej71#

问题是,默认情况下std::set使用std::less进行比较。请读取here
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;
    }

你可以使用一个单独的Functor,一个Lambda,一个自由函数,或者,你可以把这个函数添加到你的Node中,然后把它作为Functor定义的第二个参数。
所以,你有很多种方法,让我用最后一种方法作为例子。
请参阅:

#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;
}

相关问题