I am adding another answer to this question since no one has touched on a key point at this time.
Everyone tells you that you need to create a hash function for unordered_set<unsigned> , and that is correct. You can do this by specializing in std::hash<unordered_set<unsigned>> , or you can create your own functor and use it like this:
unordered_set<unordered_set<unsigned>, my_unordered_set_hash_functor> s;
In any case, this is normal. However, there is a big problem you need to keep an eye on:
For any two unordered_set<unsigned> that compare equal ( x == y ), they should hash with the same value: hash(x) == hash(y) . If you do not follow this rule, you will receive runtime errors. Also note that the following two unordered_set compare equals (pseudo-code is used here for clarity):
{1, 2, 3} == {3, 2, 1}
Therefore, hash({1, 2, 3}) should equal hash({3, 2, 1}) . Unordered containers, on the other hand, have an equality operator, where order doesn't matter. Thus, however, you create your own hash function, its result should be independent of the order of elements in the container.
Alternatively, you can replace the equality predicate used in unordered_set to keep it in order:
unordered_set<unordered_set<unsigned>, my_unordered_set_hash_functor, my_unordered_equal> s;
The burden of obtaining all of this right does:
unodered_set<set<unsigned>, my_set_hash_functor>
look pretty attractive. You still need to create a hash functor for set<unsigned> , but now you do not have to worry about getting the same hash code for {1, 2, 3} and {3, 2, 1} . Instead, you should make sure that these hash codes are different.
I note that Walter's answer gives a hash functor that has the correct behavior: it ignores the order when computing the hash code. But then his answer (at present) tells you that this is not a good solution. :-) This is a really good solution for unordered containers. An even better solution would be to return the sum of the individual hashes instead of hashing the sum of the elements.