I have a problem putting data into an unordered_map using a struct as key:
typedef struct osdpi_flow_identificator {
u32 lower_ip;
u32 upper_ip;
u16 lower_port;
u16 upper_port;
u8 protocol;
} osdpi_flow_identificator_t;
// custom hash function for osdpi_flow_identificator
struct osdpi_flow_hash {
std::size_t operator() (osdpi_flow_identificator * key) const {
hash hash_function;
std::size_t returnValue =
hash_function(key->lower_ip)
+ hash_function(key->upper_ip)
+ hash_function(key->lower_port)
+ hash_function(key->upper_port)
+ hash_function(key->protocol);
printf(" calculated hash: %i\n", returnValue);
return returnValue;
}
};
typedef unordered_map <osdpi_flow_identificator*, osdpi_flow*, osdpi_flow_hash> osdpi_flows_hashmap;
typedef osdpi_flows_hashmap::value_type 开发者_开发百科osdpi_flows_pair;
static osdpi_flows_hashmap osdpi_flows;
My problem is that the hash function returns the same value for osdpi_flow_identificators having the same value, but
osdpi_flow_identificator * flow_id = new osdpi_flow_identificator;
osdpi_flows_hashmap::const_iterator iter;
iter = osdpi_flows.find(flow_id);
if (iter != osdpi_flows.end()) {
...
doesn't find it, although an entry with a flow_id having exactly the same values, is already in the hash map. I verified it, by outputting the whole hash map and also the hash function prints out the same value. So it's quite hard for me to understand, why unordered_map can't find the entry with the same hash.
I also tried to overload operator== and operator<, which I sometimes found as tip in the net, but those functions also were not called.
What solves the issue, but, of course, later ends up with a segmentation fault, is to leave flow_id uninitialized - then the entry can be found correctly.
Any help is appreciated!
Thanks Steffen
Ok, I finally found it :-)
In fact you need to define an EqualOperator for your hash, since you are using pointers. It should be something like :
struct Eq
{
bool operator() ( osdpi_flow_identificator * id1, osdpi_flow_identificator * id2) const
{
id1->lower_ip == id2->lower_ip && // compare all fields.
}
};
then your hashmap declaration becomes
typedef unordered_map <osdpi_flow_identificator*, osdpi_flow*, osdpi_flow_hash, Eq> osdpi_flows_hashmap;
Another way to do it is to store objects in the hashmap, instead of pointers. It depends if you really want pointers in it.
精彩评论