Search code examples
hashhashtableunordered-map

unorder_map<float, short> Why does this work?


I am using an unordered_map<float, unsigned short> to implement a hash table in C++.

I know that using floats as keys to a hash table is a bad idea under most circumstances because comparing them is error-prone. However, under these circumstances, I am reading the floats in from large files and their precision is known and constant.

However, I would like to know the details of how unordered_map is hashing my floats in order to estimate collision frequency. I am not overriding the default hash implementation when I create the unordered_map. According to the documentation, the default hash function is std::hash<Key>. Which in my case is std::hash<float>. However, when I look at the std::hash documentation, it is only defined for "template arguments of type char*, const char*, crope, wrope, and the built-in integral types".

Does anyone know what function is being called to hash the values as I add them to the unordered_map?

unordered_map - http://msdn.microsoft.com/en-us/library/bb982522.aspx

std::hash - http://www.sgi.com/tech/stl/hash.html#1


Solution

  • According to the C++11 standard, float is supported for std::hash as well. The actual hash function is implementation dependent, so even if you can figure out collision frequency for your current compiler a newer version or a different compiler may implement a different hash function. Here is the full list of std::hash specializations:

    template <> struct hash<bool>;
    template <> struct hash<char>;
    template <> struct hash<signed char>;
    template <> struct hash<unsigned char>;
    template <> struct hash<char16_t>;
    template <> struct hash<char32_t>;
    template <> struct hash<wchar_t>;
    template <> struct hash<short>;
    template <> struct hash<unsigned short>;
    template <> struct hash<int>;
    template <> struct hash<unsigned int>;
    template <> struct hash<long>;
    template <> struct hash<unsigned long>;
    template <> struct hash<long long>;
    template <> struct hash<unsigned long long>;
    template <> struct hash<float>;
    template <> struct hash<double>;
    template <> struct hash<long double>;
    template <class T> struct hash<T*>;