14

This is weird.. the following code (which I managed to compile thanks to Cassio Neri) is compiling without any error.. by the way either hashing_func nor key_equal_func do get called (the couts aren't showing in the console window)

#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; } 

I'm using MSVC2012, any hint on what could be the problem?

1

2 Answers 2

23

You have to specify hash/compare functions with template arguments, not in the constructor. Here is an example:

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); 
Sign up to request clarification or add additional context in comments.

1 Comment

is there no way to pass a function pointer instead of these hasher functors which cause half a dozen lines of garbage boilerplate
11

The problem is that you need to pass the types of your hash function and hash_key_equal function to your unordered_map, and then the actual functions to the ctor of the map.

Your unordered_map definition should look like this:

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>); 

The unordered_map is a template and it looks like this:

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; 

which means if you want to pass new Hash and KeyEqual functions you have to tell the template the types of these things.

Link isn't accessible anymore (Request Update): Live Example

2 Comments

Got it: the templated function had default parameters.. functions can deduce templated parameters from their arguments but if I don't specify them I might use default ones and get errors. Thank you Tony!! This wasn't an easy catch in my opinion!!
What the meaning of the parameter n? Size of hash-table?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.