如何使自定义类型用作unordered_map中的键

时间:2018-10-15 02:21:39

标签: c++ stl

我正在尝试使自定义哈希表适用于自定义类型。 引用unordered_map constructor error (equal_to templated function)

我有:

typedef pair<int, int> tCoord;
struct hashing_func {
    unsigned long operator()(const tCoord& key) const {
        unsigned long hash = 0;
        int h1 = key.first;
        int h2 = key.second;
        return h1 ^ (h2 << 1);

    }
};

struct key_equal_fn {
    bool operator()(const tCoord& t1, const tCoord& t2) const {
        return t1.first == t2.first && t1.second == t2.second;
    }
};

unordered_map<tCoord, int, hashing_func, key_equal_fn> coord2cnt;
unordered_map<tCoord, int, hashing_func, key_equal_fn>::iterator iter;
iter = coord2cnt.find(coord);

此代码段未编译,并抱怨缺少对find()的函数调用:

error: no matching member function for call to 'find'

也尝试将其用作coord2cnt[coord],但在缺少[]运算符时也遇到了错误。

我使用的是旧版本的g ++ 4.2,但是可以很好地编译以下内容(来自上面的链接):

typedef unordered_map<string, string, hashing_func, key_equal_fn> MapType;
MapType::size_type n = 5;
MapType mymap(n, hashing_func(), key_equal_fn());

还想知道为什么这种类型的定义会起作用,即在第一个参数中指定5。在unordered_map API中似乎缺少这种定义方式?

有人知道这里出了什么问题吗? 谢谢!

更新:如前所述,字符串是一个内部类,具有内置的哈希函数。因此,我改掉了在此处使用自定义类型的问题。

2 个答案:

答案 0 :(得分:0)

作为字符串的key的unordered_map在内部处理。您不必将字符串的哈希函数定义为键。

如果要传递类或结构作为键。然后,您必须为其定义哈希函数,以计算冲突最少的键的哈希索引。要使用.find查找结构或类对象,请在所使用的结构或类中重载布尔运算符==。

示例:

#include <iostream>
#include<unordered_map>
int main() {
  std::unordered_map<std::string, int> myMap;
  myMap.insert({"asd", 1});
  myMap.insert({"qwe", 2});
  std::string input;
  std::cout<<"Enter String: ";
  std::cin>>input;
  std::unordered_map<std::string, int>::iterator it = myMap.find(input);

  if(it != myMap.end())
    std::cout<<"Found";
  else
    std::cout<<"Not Found";
}

答案 1 :(得分:-1)

您的函数“ key_equal_fn”的自定义类型为[string,string], 与“ text2cnt”不匹配的

如果要以完全专业的模板方式进行操作,怎么办:

template <typename T>
struct key_equal_fn {
    bool operator()(const T& t1, const T& t2) const {
        return t1==t2;
    }
};

template<>
struct key_equal_fn<string> {
    bool operator()(const string& t1, const string& t2) const {
        return !(t1.compare(t2));
    }
};

unordered_map<string, string, hashing_func, key_equal_fn<string> > text2cnt;
unordered_map<string, string, hashing_func, key_equal_fn<string> >::iterator iter;