The new C++11 standard has unordered containers. In particular, the std::unordered_map<Key, Value>
stores a std::pair<Key, Value>
in a location based on std::hash<Key>
(default hash function). Similarly, the std::unordered_set<Key>
stores a Key in a location based on std::hash<Key>
.
My question is: how can one store only the Value of a Key-Value pair, in a location based on std::hash<Key>
? This would be useful if one uses a perfect hash function, i.e. one for which different Keys map to different hash indices (so there is never collision resolution required).
An unordered_set only uses the key, and an unordered_map uses both the key and the value, so the unordered STL containers in the new C++11 standard do not seem to allow such customization. What would be a good way to get such a data structure from the existing STL containers?
More generally, how can one store a std::pair<T, Value>
in a location based on std::hash<Key>
, where T
is a type representing a signature of the Key? E.g. if Key is a large data structure, I would like to compute a 64-bit hash key and split this into two 32 bit parts: the upper 32 bits together with the Value form a std::pair<uint32_t, Value>
, and the lower 32 bits determine the location where this pair is stored.
An application where this would be useful is e.g. computer chess, where a position (several kilobytes in some programs) as the Key type is hashed into a 64-bit key, of which only the upper 32 bits and some search related information as the Value type are stored as a std::pair
(usually only 16 bytes in total) in a location based on the lower 32 bits of the hash key.
There is no general-purpose way to perform operations on a hash without continuous access to the hash values. For example, suppose the hash internally uses a tree. To add a new node to the hash, you need to compare its hash value to the hash value of existing nodes on the tree. How can you do that if you didn't store their values in the tree?
What you're asking for is probably not impossible, but none of the typical hashing algorithms can do it. And there doesn't seem to be any point anyway, you have to store something to make the collection traversable, and it's hard to see how something other than the hash could ever work as well as the hash, since that's what you're searching for.
If the hash is "too big", use a hash of the hash. (Of course, then you have to deal with hash collisions.)