2013-04-19 13 views
38

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).zadeklarowanie parametru priority_queue w języku C++ przy użyciu niestandardowego komparatora

Co Mam aktualnie jest:

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

Z jakiegoś powodu jestem coraz Error: "Compare" is not a type name

Zmiana deklaracji priority_queue <Node, vector<Node>, bool Compare>

daje mi Error: expected a '>'

Ja również wypróbowano:

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 powinienem poprawnie zadeklarować mój priority_queue?

Odpowiedz

47

Należy zadeklarować klasa Compare i przeciążenie operator() dla niej tak:

class Foo 
{ 

}; 

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

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

Lub, jeśli z jakichś powodów nie może uczynić go jako klasa, można użyć std::function do niego:

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; 
} 
+0

Idealne, właśnie to, czego szukałem. Nigdy nie myślałem, że zrobię oddzielną klasę. Czy pierwszy przykład można uznać za lepszy styl? –

+2

@StevenMorad, wolę używać klasy z przeciążonym 'operator()', to wygląda na prostsze. – soon

+0

@soon Dlaczego przeciążamy operatora()? Czy jest to związane z wewnętrznym wdrażaniem mechanizmów priority_queues? Przeciążanie> lub Piyush

9

Trzeci parametr szablonu musi być klasą, która ma przeciążone operator()(Node,Node). Więc trzeba będzie utworzyć klasę w ten sposób:

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

I wtedy użyć tej klasy jako trzeci parametr szablonu takich jak to:

priority_queue<Node, vector<Node>, ComparisonClass> q; 
+2

Metoda operatora musi być jawna. – knezi

+0

Trzeci szablon nie musi być klasą. Może to być typ funkcji. –

3

Odpowiadając na zapytanie bezpośrednio:

I'm trying to declare a priority_queue of nodes, using bool Compare(Node a, Node b) as the comparator function

What I currently have is:

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

For some reason, I'm getting Error:

"Compare" is not a type name 

Kompilator mówi dokładnie, co jest nie tak: Compare nie jest nazwą typu, ale instancją funkcji, która pobiera dwie wartości: Nodes i zwraca wartość bool.
Co potrzebne jest, aby określić typ wskaźnika funkcję:
std::priority_queue<Node, std::vector<Node>, bool (*)(Node, Node)> openSet(Compare)

1

Zaakceptowanych odpowiedź sprawia, że ​​uważasz, że należy użyć klasy lub std::function jako komparatora. To nie jest prawda! cute_ptr's answer pokazał jak przekazać funkcję konstruktora, ale jest prostszy sposób:

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

Oznacza to, że nie ma potrzeby, aby wyraźnie zakodować wpisać funkcję, można pozwolić kompilator zrobić to za Ciebie.