Diaz
Diaz

Reputation: 987

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

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

Upvotes: 4

Views: 2125

Answers (2)

fredoverflow
fredoverflow

Reputation: 263350

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!

Upvotes: 8

skortzy
skortzy

Reputation: 169

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

Upvotes: 3

Related Questions