I’m trying to form a std::tr1::unordered_map where the key type is a struct that includes a callback function, for which I’m using std::tr1::function. I’m running into two problems: 1) the function object does not appear to be equality comparable, as the Boost.Function documentation indicates; 2) I don’t see how to implement the hash function, since I can’t get a regular function pointer (or something else I could use for hashing) from the function object.
Here’s the example code:
#include <boost/functional/hash.hpp>
#include <boost/tr1/functional.hpp>
#include <boost/tr1/unordered_map.hpp>
#include <iostream>
int f(int) {}
typedef std::tr1::function<int(int)> callback;
struct Record
{
callback func;
// More members...
// Requirements for unordered_map key.
friend bool operator==(Record const & lhs, Record const & rhs)
{ return lhs.func == rhs.func; } // error: ambiguous
friend std::size_t hash_value(Record const & arg)
{ return boost::hash<void *>(arg.func.get()); } // error: no member get()
};
int main()
{
std::tr1::unordered_map<Record, int> map;
Record a = {f};
map[a] = 0;
return 0;
}
Here’s some detail on the first error :
test.cpp: In function bool operator==(const Record&, const Record&):
test.cpp:16: error: ambiguous overload for operator== in lhs->Record::func == rhs->Record::func
test.cpp:16: note: candidates are: operator==(void (boost::function1<int, int>::dummy::*)(), void (boost::function1<int, int>::dummy::*)()) <built-in>
<root>/boost/function/function_template.hpp:1024: note: void boost::operator==(const boost::function1<R, T0>&, const boost::function1<R, T0>&) [with R = int, T0 = int]
For the second error, obviously there’s no function<…>::get member, but what should I use instead?
I’m using Boost version 1.42 and g++ 4.2.2. Thanks for any help.
Update
The answer to the posted question is “you can’t.” tr1::function objects are hashable (e.g., using boost::hash), but are not equality comparable. If you want to use a function in the hash key, rethink the approach or find a workaround.
It would seem that TR1 specifically requires that
remain undefined (3.7.2.6), so at the very least you’d have to find another way to get equality. Furthermore, I’m not finding any reference to a
get()member method in the paper either.