2010-01-20 14 views
10

Estoy tratando de definir un tipo de desorden_map que tenga una función hash personalizada y una función de comparación de igualdad. Los prototipos de las funciones de estas funciones son las siguientes:Definición de la función hash personalizada y función de igualdad para unordered_map

//set<Vertex3DXT*> is the type of the key; Cell3DXT* is the type of the value 
size_t VertexSetHashFunction(set<Vertex3DXT*> vertexSet); //hash function 
bool SetEqual(set<Vertex3DXT*> a, set<Vertex3DXT*> b); //equality 

he declarado estos prototipos de función y luego trato de declarar el tipo de la siguiente manera:

typedef std::tr1::unordered_map<set<Vertex3DXT*>, Cell3DXT*, VertexSetHashFunction, SetEqual> CellDatabaseMapType; 

pero dice que el VertexSetHashFunction y SetEqual son argumentos de tipo de plantilla no válidos. La documentación es confusa porque no dice exactamente qué tipo se supone que son los argumentos de la plantilla: ¿se supone que debo darle la función como lo hice aquí, o hay algún otro tipo de objeto que encapsula la función (porque el la documentación habla sobre el "tipo de objeto función hash")?

+0

¿Aún te preocupa esta pregunta? – Omnifarious

+0

Gracias por el recordatorio: una de las respuestas fue la respuesta que quería, pero me olvidé de aceptarla. Lo acabo de aceptar ahora. – Alex319

Respuesta

9

Desafortunadamente, esas funciones se deberían declarar como operador() en una clase. De esta manera:

class VertexSetHashFunction { 
    public: 
    ::std::size_t operator()(const ::std::set<Vertex3DXT*> &vertexSet) const; 
}; 
class SetEqual { 
    public: 
    bool operator()(const ::std::set<Vertex3DXT*> &a, const ::std::set<Vertex3DXT*> &b) const; 
}; 

Usted no tiene que modificar los argumentos para ser referencias const, pero recomendaría encarecidamente. Hacer una copia de un :: std :: set es relativamente costoso y no debes hacerlo a menos que sea absolutamente necesario.

La const posterior es solo porque el operador no modifica en absoluto el estado de clase, sobre todo porque no hay ninguno. Es bueno decirlo explícitamente.

Alternativamente, podría definir su propia especialización de la plantilla :: std :: hash. De hecho, lo recomendaría si hay una forma estándar de que desee ese conjunto en particular, ya que esta plantilla se utiliza de forma predeterminada si no proporciona una función de hash a unordered_map o unordered_set y cualquier otra cosa que necesite una función de control.

5

Necesita funtores.

struct VertexSetHashFunction { 
    size_t operator() (const set<Vertex3DXT*>& vertexSet) const { return /*whatever*/; } 
}; 

struct SetEqual { 
    bool operator() (const set<Vertex3DXT*>& a, const set<Vertex3DXT*>& b) const { return /*whatever*/; } 
}; 
+1

Retorno 0 es una idea terrible. – njamesp

+9

@njamesp: ¿En serio crees que quiero que el OP implemente la función exactamente así cuando escribo 'return false;' en SetEqual? * suspiro * – kennytm

+0

Nota, como en el ejemplo de KennyTM, los funtores también podrían ser estructuras. –