c++ - 结构作为 unordered_map 的键

标签 c++

我在使用结构作为键将数据放入 unordered_map 时遇到问题:


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;

我的问题是散列函数为具有相同值的 osdpi_flow_identificators 返回相同的值,但是


 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()) {
  ...

没有找到它,尽管具有完全相同值的 flow_id 的条目已经在 HashMap 中。我验证了它,通过输出整个 HashMap ,哈希函数也打印出相同的值。所以我很难理解,为什么 unordered_map 找不到具有相同哈希值的条目。

我还尝试过重载 operator== 和 operator<,我有时会在网上找到这些提示,但这些函数也没有被调用。

解决这个问题的方法是让 flow_id 保持未初始化状态,但当然后来会出现段错误 - 然后可以正确找到该条目。

感谢任何帮助!

谢谢 史蒂芬

最佳答案

好吧,我终于找到了:-)

事实上,您需要为散列定义一个 EqualOperator,因为您使用的是指针。 它应该是这样的:

struct Eq
{
  bool operator() ( osdpi_flow_identificator * id1, osdpi_flow_identificator * id2) const
  {
    id1->lower_ip == id2->lower_ip && // compare all fields.
  }
};

然后你的 hashmap 声明变成了

typedef unordered_map <osdpi_flow_identificator*, osdpi_flow*, osdpi_flow_hash, Eq> osdpi_flows_hashmap;

另一种方法是将对象存储在 HashMap 中,而不是指针。这取决于您是否真的想要其中的指针。

关于c++ - 结构作为 unordered_map 的键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3317978/

相关文章:

c++ - 如何使用 C++ 库算法分区函数进行快速排序?

c++ - 在 Windows 过程中调用指向指向 C 函数的函数的成员指针会使应用程序崩溃

if-else 中的 C++11 lambda 函数定义

c++ - 如何检查文件是否已被另一个 C++ 应用程序打开?

c++ - 数组的最小值

c++ - "byte"包含奇怪字符的数据类型

c++ - 在 C++ 中使用抽象基类和模板进行重构

C++ 访问对象,QT

c++ - 启用 OpenCV cuda 的构建不起作用

c++ - 在 OSX 上与 C++ 中的 libconfig 链接