it-swarm.com.de

Deklarieren einer priority_queue in c ++ mit einem benutzerdefinierten Komparator

Ich versuche, ein priority_queue of nodes Zu deklarieren, wobei bool Compare(Node a, Node b) als Komparatorfunktion verwendet wird (die außerhalb der Knotenklasse liegt).

Was ich derzeit habe, ist:

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

Aus irgendeinem Grund erhalte ich Error: "Compare" is not a type name

Änderung der Deklaration in priority_queue <Node, vector<Node>, bool Compare>

gibt mir Error: expected a '>'

Ich habe auch versucht:

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

Wie soll ich meinen priority_queue Korrekt deklarieren?

58
Steven Morad

Sie sollten eine Klasse Compare deklarieren und operator() wie folgt überladen:

class Foo
{

};

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

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

Oder wenn Sie es aus irgendeinem Grund nicht als Klasse schaffen, können Sie std::function dafür:

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

Der dritte Template-Parameter muss eine Klasse sein, die operator()(Node,Node) überladen hat. So müssen Sie eine Klasse erstellen:

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

Und dann werden Sie diese Klasse wie folgt als dritten Template-Parameter verwenden:

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

Die akzeptierte Antwort lässt Sie glauben, dass Sie eine Klasse oder ein std::function als Vergleicher. Das ist nicht wahr! cute_ptrs Antwort zeigte, wie eine Funktion an den Konstruktor übergeben wird, aber es gibt einen einfacheren Weg:

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

Das heißt, Sie müssen den Funktionstyp nicht explizit codieren, sondern können dies vom Compiler für Sie tun lassen.

11
Cris Luengo

Beantworten Sie Ihre Frage direkt:

Ich versuche, einen priority_queue Von Knoten mit bool Compare(Node a, Node b) as the comparator function zu deklarieren.

Was ich derzeit habe, ist:

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

Aus irgendeinem Grund erhalte ich den Fehler:

"Compare" is not a type name

Der Compiler sagt Ihnen genau, was falsch ist: Compare ist kein Typname, sondern eine Instanz einer Funktion, die zwei Nodes akzeptiert und ein bool zurückgibt.
Sie müssen den Funktionszeigertyp angeben:
std::priority_queue<Node, std::vector<Node>, bool (*)(Node, Node)> openSet(Compare)

5
cute_ptr

Man kann auch eine Lambda-Funktion verwenden.

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