Jonny
Jonny

Reputation: 16338

Unordered set in C++, why is hash needed?

I just want to store a couple of objects in an unordered set. Creating a few sets,

auto set1 = std::unordered_set<Myclass>();

I sometimes get errors like this, a lot:

Implicit instantiation of undefined template 'std::__1::hash'

Is there no other alternative to unordered_set that will work out of the box? And why is "hash" needed?

Upvotes: 2

Views: 2279

Answers (1)

TartanLlama
TartanLlama

Reputation: 65770

std::unordered_set indexes the values in its storage by hashing the key you use, much like a hash table or the C++ std::unordered_map implementation.

If you don't want to write a hash function for Myclass, just use std::set instead. This might perform worse than if you defined a hash function and used std::unordered_set, but might be worth it if writing a hash function would be difficult for your class. Depends on the class and your application.

If you want to use std::unordered_set, you need to provide a hash function for Myclass. Either provide a specialization of std::hash for your class, or provide a hashing policy to std::unordered_set.

//specialize std::hash
namespace std
{
    template<>
    struct hash<Myclass>
    {
        typedef Myclass argument_type;
        typedef std::size_t result_type;

        result_type operator()(argument_type const& s) const
        {
            //some code to hash a Myclass object
        }
    };
}
auto set1 = std::unordered_set<Myclass>();   

//hashing policy version
class MyclassHash
{
public:
    std::size_t operator()(Myclass const& s) const 
    {
        //some code to hash a Myclass object
    }
};
auto set1 = std::unordered_set<Myclass, MyclassHash>();

Upvotes: 6

Related Questions