2010-01-20 2 views
10

Sto provando a definire un tipo di unordered_map che ha una funzione di hash personalizzata e una funzione di confronto di uguaglianza. I prototipi di funzione di queste funzioni sono le seguenti:Definizione della funzione hash personalizzata e della funzione di uguaglianza per 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 

ho questi prototipi di funzione dichiarata e poi cerco di dichiarare il tipo come segue:

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

ma si dice che il VertexSetHashFunction e SetEqual sono argomenti del tipo di modello non validi. La documentazione è confusa perché non dice esattamente quale tipo si suppone che gli argomenti del template siano - devo solo dargli la funzione come ho fatto qui, o c'è qualche altro tipo di oggetto che incapsula la funzione (perché il la documentazione parla del "tipo di oggetto funzione hash")?

+0

Ti importa ancora di questa domanda? – Omnifarious

+0

Grazie per il promemoria - una delle risposte era la risposta che volevo ut ho appena dimenticato di accettarlo. L'ho appena accettato ora. – Alex319

risposta

9

Tali funzioni devono essere dichiarate come operatori() in una classe, sfortunatamente. In questo modo:

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

Non è necessario modificare gli argomenti per essere riferimenti const, ma lo consigliamo vivamente. Fare una copia di un :: std :: set è relativamente costoso e non dovresti farlo a meno che non sia assolutamente necessario.

Il const finale è solo perché l'operatore non modifica affatto lo stato della classe, soprattutto perché non ce n'è. È bello dirlo in modo esplicito.

In alternativa, è possibile definire la propria specializzazione del modello :: std :: hash. In realtà lo consiglio se esiste un modo standard in cui si desidera eseguire l'hash di quel determinato set perché questo modello viene utilizzato per impostazione predefinita se non si fornisce una funzione hash a unordered_map o unordered_set ea qualsiasi altra cosa che richiede una funzione hash.

5

Sono necessari i funtori.

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

Il ritorno 0 è una pessima idea. – njamesp

+9

@njamesp: Pensi seriamente che io voglia che l'OP implementa esattamente la funzione quando scrivo 'return false;' in SetEqual? * sigh * – kennytm

+0

Nota, come nell'esempio di KennyTM, i funtori potrebbero anche essere delle strutture. –