Próbuję zadeklarować priority_queue of nodes
, używając bool Compare(Node a, Node b)
jako funkcji komparatora (która znajduje się poza klasą węzła).
Obecnie posiadam:
priority_queue<Node, vector<Node>, Compare> openSet;
Z jakiegoś powodu rozumiem Error: "Compare" is not a type name
Zmiana deklaracji na priority_queue <Node, vector<Node>, bool Compare>
daje mi Error: expected a '>'
Próbowałem też:
priority_queue<Node, vector<Node>, Compare()> openSet;
priority_queue<Node, vector<Node>, bool Compare()> openSet;
priority_queue<Node, vector<Node>, Compare<Node, Node>> openSet;
Jak prawidłowo zgłosić moje priority_queue
?
c++
std
priority-queue
Steven Morad
źródło
źródło
operator()
, wygląda na prostszą.pritority_queue
. Możliwe jest przeciążenieoperator<
i użycie wbudowanegostd::less
komparatora jednakbool Compare(Node a, Node b)
zadeklarowanego poza klasąNode
, zgodnie z pytaniem.Przyjęta odpowiedź sprawia, że uważasz, że musisz użyć klasy lub klasy
std::function
jako komparatora. To nie jest prawda! Jak pokazuje odpowiedź cute_ptr , możesz przekazać wskaźnik funkcji do konstruktora. Jednak składnia, aby to zrobić, jest znacznie prostsza niż tutaj pokazana:class Node; bool Compare(Node a, Node b); std::priority_queue<Node, std::vector<Node>, decltype(&Compare)> openSet(Compare);
Oznacza to, że nie ma potrzeby jawnego kodowania typu funkcji, możesz pozwolić kompilatorowi zrobić to za Ciebie
decltype
.Jest to bardzo przydatne, jeśli komparatorem jest lambda. Nie można określić typu lambda w żaden inny sposób niż za pomocą
decltype
. Na przykład:auto compare = [](Node a, Node b) { return a.foo < b.foo; } std::priority_queue<Node, std::vector<Node>, decltype(compare)> openSet(compare);
źródło
Compare
jest to lambda, dla której nie da się napisać deklaracji), nie znam żadnych pułapek.f
wcześniej i wtedy wymienićCompare
zf
?Compare
może być tam funkcją lambda, jak wauto Compare = [](){};
. Ale musiszdecltype(Compare)
raczej użyć niżdecltype(&Compare)
.Trzeci parametr szablonu musi być klasą, która została
operator()(Node,Node)
przeciążona. Będziesz więc musiał utworzyć klasę w ten sposób:class ComparisonClass { bool operator() (Node, Node) { //comparison code here } };
Następnie użyjesz tej klasy jako trzeciego parametru szablonu w następujący sposób:
priority_queue<Node, vector<Node>, ComparisonClass> q;
źródło
Odpowiadając bezpośrednio na Twoje pytanie:
Kompilator mówi dokładnie, co jest nie tak:
Compare
nie jest nazwą typu, ale instancją funkcji, która przyjmuje dwaNodes
i zwracabool
.Potrzebujesz określić typ wskaźnika funkcji:
std::priority_queue<Node, std::vector<Node>, bool (*)(Node, Node)> openSet(Compare)
źródło
Można też użyć funkcji lambda.
auto Compare = [](Node &a, Node &b) { //compare }; std::priority_queue<Node, std::vector<Node>, decltype(Compare)> openset(Compare);
źródło
Najpierw musisz zdefiniować porównanie. Można to zrobić na 3 sposoby:
Jest łatwy w użyciu class / struct, ponieważ łatwo go zadeklarować, po prostu napisz tę linię kodu nad wykonywanym kodem
struct compare{ public: bool operator()(Node& a,Node& b) // overloading both operators { return a.w < b.w: // if you want increasing order;(i.e increasing for minPQ) return a.w > b.w // if you want reverse of default order;(i.e decreasing for minPQ) } };
Kod telefoniczny:
priority_queue<Node,vector<Node>,compare> pq;
źródło
Na wypadek, gdyby to komuś pomogło:
static bool myFunction(Node& p1, Node& p2) {} priority_queue <Node, vector<Node>, function<bool(Node&, Node&)>> pq1(myFunction);
źródło
wolą struct i to właśnie robią std :: Greater
struct Compare { bool operator()(Node const&, Node &) {} }
źródło