web-dev-qa-db-fra.com

déclarer une priority_queue en c ++ avec un comparateur personnalisé

J'essaie de déclarer un priority_queue of nodes, En utilisant bool Compare(Node a, Node b) comme fonction de comparaison (qui est en dehors de la classe de noeud).

Ce que j'ai actuellement c'est:

priority_queue<Node, vector<Node>, Compare> openSet;

Pour une raison quelconque, je reçois Error: "Compare" is not a type name

Changer la déclaration en priority_queue <Node, vector<Node>, bool Compare>

me donne Error: expected a '>'

J'ai aussi essayé:

priority_queue<Node, vector<Node>, Compare()> openSet;
priority_queue<Node, vector<Node>, bool Compare()> openSet;
priority_queue<Node, vector<Node>, Compare<Node, Node>> openSet; 

Comment dois-je déclarer correctement mon priority_queue?

58
Steven Morad

Vous devez déclarer une classe Compare et la surcharger operator() comme ceci:

class Foo
{

};

class Compare
{
public:
    bool operator() (Foo, Foo)
    {
        return true;
    }
};

int main()
{
    std::priority_queue<Foo, std::vector<Foo>, Compare> pq;
    return 0;
}

Ou, si pour certaines raisons vous ne pouvez pas le faire en classe, vous pouvez utiliser std::function pour ça:

class Foo
{

};

bool Compare(Foo, Foo)
{
    return true;
}

int main()
{
    std::priority_queue<Foo, std::vector<Foo>, std::function<bool(Foo, Foo)>> pq(Compare);
    return 0;
}
75
awesoon

Le troisième paramètre de modèle doit être une classe qui a surchargé operator()(Node,Node). Vous devrez donc créer une classe de cette façon:

class ComparisonClass {
    bool operator() (Node, Node) {
        //comparison code here
    }
};

Et vous utiliserez ensuite cette classe comme troisième paramètre de modèle, comme ceci:

priority_queue<Node, vector<Node>, ComparisonClass> q;
13
Mic

La réponse acceptée vous fait croire que vous devez utiliser une classe ou un std::function comme comparateur. Ce n'est pas vrai! réponse de cute_ptr a montré comment passer une fonction au constructeur, mais il existe un moyen plus simple:

priority_queue<Node, vector<Node>, decltype(&Compare)> openSet(Compare);

Autrement dit, il n'est pas nécessaire de coder explicitement le type de la fonction, vous pouvez laisser le compilateur le faire pour vous.

11
Cris Luengo

Répondre à votre question directement:

J'essaie de déclarer un priority_queue De nœuds, en utilisant bool Compare(Node a, Node b) as the comparator function

Ce que j'ai actuellement c'est:

priority_queue<Node, vector<Node>, Compare> openSet;

Pour une raison quelconque, je reçois une erreur:

"Compare" is not a type name

Le compilateur vous dit exactement ce qui ne va pas: Compare n'est pas un nom de type, mais une instance d'une fonction qui prend deux Nodes et retourne un bool.
Ce dont vous avez besoin est de spécifier le type de pointeur de fonction:
std::priority_queue<Node, std::vector<Node>, bool (*)(Node, Node)> openSet(Compare)

5
cute_ptr

On peut aussi utiliser une fonction lambda.

auto Compare = [](Node &a, Node &b) { //compare };
std::priority_queue<Node, std::vector<Node>, decltype(Compare)> openset(Compare);
2
bornfree