C++17 STL Cookbook
上QQ阅读APP看书,第一时间看更新

How it works...

Usually, when we instantiate a hash-based map implementation like std::unordered_map, we write:

std::unordered_map<key_type, value_type> my_unordered_map;

It is not too obvious that there happens a lot of magic in the background when the compiler creates our std::unordered_map specialization. So, let's have a look at the complete template-type definition of it:

template<
class Key,
class T,
class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator< std::pair<const Key, T> >
> class unordered_map;

The first two template types are those we filled with coord and int, which is the simple and obvious part. The other three template types are optional, as they are automatically filled with existing standard template classes, which themselves take template types. Those are fed with our choice for the first two parameters as default values.

Regarding this recipe, the class Hash template parameter is the interesting one: when we do not explicitly define anything else, it is going to be specialized on std::hash<key_type>. The STL already contains std::hash specializations for a lot of types such as std::hash<std::string>, std::hash<int>, std::hash<unique_ptr>, and many more. These classes know how to deal with such specific types in order to calculate optimal hash values from them.

However, the STL does not know how to calculate a hash value from our struct coord, yet. So what we did was to just define another specialization, which knows how to deal with it. The compiler can now go through the list of all std::hash specializations it knows, and will find our implementation to match it with the type we provided as key type.

If we did not add a new std::hash<coord> specialization, and named it my_hash_type instead, we could still use it with the following instantiation line:

std::unordered_map<coord, value_type, my_hash_type> my_unordered_map;

That is obviously more to type, and not as nice to read as when the compiler finds the right hashing implementation itself.