Unordered_map с пользовательскими хэшированием/равными функциями - функции не вызываются
Это странно.. следующий код (который мне удалось скомпилировать благодаря Cassio Neri) компилируется без каких-либо ошибок.. кстати, либо hashing_func, либо key_equal_func do call call (выходы не отображаются в окне консоли)
#include <iostream>
#include <string>
#include <unordered_map>
#include <algorithm>
#include <functional>
using namespace std;
unsigned long hashing_func(string key)
{
cout << "Hashing called";
unsigned long hash = 0;
for(int i=0; i<key.size(); i++)
{
hash += (71*hash + key[i]) % 5;
}
return hash;
}
template<class T> bool key_equal_fn(T t1, T t2)
{
return t1 == t2;
}
template <> bool key_equal_fn<string>(string t1, string t2)
{
cout << "Equal called";
return !(t1.compare(t2));
}
int main ()
{
unordered_map<string, string>::size_type n = 5;
unordered_map<string, string> mymap(n, (const std::hash<string> &)hashing_func,
(const std::equal_to<string> &)(function<bool(string,string)>(key_equal_fn<string>))) ;
bool case_insensitive = mymap.key_eq()("test","TEST");
mymap["paul"] = "jenna";
mymap["frank"] = "ashley";
if(mymap["paul"] == mymap["frank"])
cout << "equal" << endl;
return 0;
}
Я использую MSVC2012, любой намек на то, что может быть проблемой?
Ответы
Ответ 1
Проблема в том, что вам нужно передать типы вашей хеш-функции и функции hash_key_equal на ваш unordered_map, а затем фактические функции для ctor карты.
Ваше определение unordered_map должно выглядеть следующим образом:
unordered_map<
std::string,
std::string,
std::function<unsigned long(std::string)>,
std::function<bool(std::string, std::string)>
> mymap(n, hashing_func, key_equal_fn<std::string>);
unordered_map
является шаблоном и выглядит следующим образом:
template<
class Key,
class T,
class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator<std::pair<const Key, T>>
> class unordered_map;
что означает, что если вы хотите передать новые функции Hash
и KeyEqual
, вы должны указать шаблону типы этих вещей.
Ссылка больше не доступна (запрос обновления):
Живой пример
Ответ 2
Вы должны указать функции hash/compare с аргументами шаблона, а не в конструкторе. Вот пример:
class Hasher
{
public:
size_t operator() (string const& key) const
{
cout << "Hashing called";
size_t hash = 0;
for(size_t i=0; i<key.size(); i++)
{
hash += (71*hash + key[i]) % 5;
}
return hash;
}
};
class EqualFn
{
public:
bool operator() (string const& t1, string const& t2) const
{
cout << "Equal called";
return !(t1.compare(t2));
}
};
unordered_map<string, string, Hasher, EqualFn> mymap(5);