2009-10-09 16 views
13

Tengo muchos problemas para que mi cola de prioridad reconozca el parámetro por el que debería ordenar. Sobrecargué al operador menor que en mi clase personalizada, pero parece que no lo usa. Aquí está el código correspondiente:Cola de prioridad de STL en la clase personalizada

Node.h

class Node 
{ 
public: 
    Node(...); 
    ~Node(); 
    bool operator<(Node &aNode); 
... 
} 

Node.cpp

#include "Node.h" 
bool Node::operator<(Node &aNode) 
{ 
    return (this->getTotalCost() < aNode.getTotalCost()); 
} 

getTotalCost() devuelve un int

main.cpp

priority_queue<Node*, vector<Node*>,less<vector<Node*>::value_type> > nodesToCheck; 

Lo ¿Me estoy perdiendo y/o estoy equivocado?

+0

Debe estar en la IA de Chai clase :) http://stackoverflow.com/questions/1517854/priorityqueue-comparison-for-pointers – Polaris878

+0

Buenas habilidades de detective;) – bmalicoat

Respuesta

21

less<vector<Node*>::value_type> significa que su comparador compara los punteros entre sí, es decir, su vector se ordenarán por la disposición en la memoria de los nodos.

que quiere hacer algo como esto:

#include <functional> 
struct DereferenceCompareNode : public std::binary_function<Node*, Node*, bool> 
{ 
    bool operator()(const Node* lhs, const Node* rhs) const 
    { 
     return lhs->getTotalCost() < rhs->getTotalCost(); 
    } 
}; 

// later... 
priority_queue<Node*, vector<Node*>, DereferenceCompareNode> nodesToCheck; 

Tenga en cuenta que tiene que ser const-correcto en su definición de totalCost.

EDIT: Ahora que C++ 11 es aquí, no necesita heredar de std :: binary_function más (lo que significa que no es necesario utilizar #include funcional)

+1

Por curiosidad: ¿por qué definir una estructura con operator() en lugar de solo una función? –

+3

Tienes que hacerlo. No puede especializar plantillas con funciones, solo tipos (excluidas circunstancias específicas). Los objetos de función son una parte muy importante de la programación STL. Un buen libro para leer es el * Effective STL * de Scott Meyer.Explica todo sobre el STL y las mejores formas de aprovecharlo. – rlbond

+0

Además, debo señalar que 'std :: less ' también es un objeto de función (es decir, una estructura con 'operator()') – rlbond

14

Necesita hacer su parámetro const, porque a partir de ahora le está dando una referencia sin costo, lo que significa que puede modificar el objeto con el que compara. (Lo cual no es, y probablemente no debería)

Usted no está siendo const-correcto. Su operator< no hace modificaciones al Nodo, por lo que la función debe ser const:

bool operator<(const Node &aNode) const; 

Después de eso, si tiene problemas para llamar a la función getTotalCost(), lo más probable es que no es const también. Marqúelo como const si no es ya:

int getTotalCost(void) const; 

Su código es ahora (más) const-correcto.

En una nota lateral, los operadores binarios son implementados por lo general fuera de la clase:

class Node 
{ 
public: 
    // ... 

    int getTotalCost(void) const; 

    // ... 
}; 

bool operator<(const Node& lhs, const Node& rhs) 
{ 
    return lhs.getTotalCost() < rhs.getTotalCost(); 
} 
+1

+1: las interfaces mínimas son cosas buenas –

+0

En realidad, tengo que estar en desacuerdo con la definición de 'operator <' fuera de la clase en algunos casos. Si está claro lo que se supone que debe hacer, no creo que sea realmente un gran problema definirlo como miembro. Además, permite el uso de Boost.Operators. – rlbond

Cuestiones relacionadas