开发者

struct as key of unordered_map

开发者 https://www.devze.com 2023-01-08 19:18 出处:网络
I have a problem putting data into an unordered_map using a struct as key: typedef struct osdpi_flow_identificator {

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消