Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use std::unordered_set in C++?

Tags:

c++

hash

I picked the concepts of hash tables in Java, so I was aware that for a generic "hash set" container to work for custom classes, one must provide definition for a hash function and an corresponding equality function.

In Java, this would mean overriding method

int hashCode()

and

boolean equals (Object o)

.

I was expecting the same logic in c++'s STL, but was having trouble understanding the syntax. Specifically, std::unordered_set<> accepts 5 template arguments (can you believe that?), which looks like a monster and makes my head spin.

So I would be appreciate it if one could give a simple example for the current toy class:

class Some{
public :
int a;
};

Of which the hash function simply returns the value of a, and the equality test functions returns true iff the values of member 'a' are the same.

Thanks

like image 717
Diaz Avatar asked Jan 10 '23 22:01

Diaz


2 Answers

Step 1: Overload operator== for your type:

bool operator==(const Some& x, const Some& y)
{
    return x.a == y.a;
}

Step 2: Specialize std::hash for your type:

namespace std
{
    template<>
    struct hash<Some>
    {
        typedef Some argument_type;
        typedef size_t result_type;

        size_t operator()(const Some& x) const
        {
            return x.a;
        }
    };
}

Step 3: A simple test:

int main()
{
    std::unordered_set<Some> test;
    test.insert(Some{42});
}

Step 4: Profit!

like image 157
fredoverflow Avatar answered Jan 17 '23 16:01

fredoverflow


I do not have a compiler, so there might be errors, but it should be something similar to:

namespace std {
  template <>
  struct hash<Some>
  {
    typedef Some argument_type;
    typedef std::size_t  result_type;

    result_type operator()(const Some & t) const
    {
       return t.a;
    }
  };
}
like image 20
skortzy Avatar answered Jan 17 '23 17:01

skortzy