I'm having some issues using unordered_set with my specialized hash function. I can insert elements without an issue, but when I try to find other elements using find or count it doesn't work. it can't find the elements that are already in the set.
Here's my hash function:
template <class T>
inline void hash_combine(std::size_t& seed, const T& v)
{
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
namespace std {
template<>
struct hash<Node>
{
std::size_t operator()(const Node &node) const
{
size_t seed = 0;
hash_combine(seed, node.getX());
hash_combine(seed, node.getY());
return seed;
}
};
}
My Node class have bunch of other member variables but I'm only combining X and Y. This should be enough since I can safely assume there cannot be 2 Nodes with same X and Y values. This is the fist time I'm getting my hands dirty with template specialization, am I doing something wrong? I think I might not be hashing them correctly.
Here's an example to further clarify my issue:
Let say I have a set called mySet that contains 4 Nodes(X Y) : <1 7> <2 7> <3 7> <1 8>
bool find1(Node *node)
{
unordered_set<Node*>::const_iterator it = mySet.find(node);
return (it != mySet.end()); //will be false
}
bool find2(Node *node)
{
return !mySet.count(node); //will be 1 (!0)
}
cout << find1(new Node(1,7)) << endl; // returns 0
cout << find2(new Node(1,7)) << endl; // returns 1
Anyone have any idea why element lookups don't work?
Thanks
Because your unordered_set
contains Node*
and not Node
, the pointers are being searched for and not the objects themselves. I don't know why find2
would return 1, unless by coincidence you have 2 objects allocated to the same place.
If you tried to use a hashing function that took a Node*
it wouldn't work either, because unordered_set
also requires a working ==
operator to compare elements.