c++boosthashcontainersunordered

Reason for boost::extension.hpp does not defining hash_value() for unordered and some other containers


From the boost documentation:

 It also implements the extension proposed by Peter Dimov in issue 6.18 of the Library Extension Technical Report Issues List (page 63), this adds support for:
...
**the standard containers**
...

However, when looking at the implementation (boost version 1.71) in extension.hpp I can see that there is a specialization only for array, vector, list, deque, set, multiset, map, multimap. The other containers forward_list, unordered_set, unordered_multiset, unordered_map and unordered_multimap are missing, as well as the container adaptors stack, queue and priority_queue. While the latter seem more or less plausible (as the container behind is another one, just the interface changed), I'm at least wondering about the other containers. Are simply not yet integrated, did they get forgotten, is it because the draft does not name them as well (why?) or is there some special reason behind?

Notes:
I'm aware of this question on SO
Why doesn't boost::hash_value support boost::unordered_set by default?
but I think this question is mainly asking about a set inside a set and additionally the question is 6 year old (which may lead to a different answer today), that why I'm asking this question.

I'm also aware that building a hash over a complete container is neither constant access nor performant, We don't need to discuss this. Sometimes you have to change memory consumption against runtime (in this case by using boost::flyweight but this requires a hash). And if class has a container as a member, well, you're there (if you're not allowed to change the class itself).


Solution

  • Unordered containers will largely have irrelevant, non-repeatable hashes.

    This is because hash(a,b,c) is not the same as hash(b,a,c) or hash(c, a, b) etc.

    Since the ordering cannot be depended and only implicitly controlled, you will never know what it means to have "identical hash". The main rule of hashes for lookup is that equivalent values should hash to the same value, but since different sets {a,b,c} as an unordered container might hash to different values while being equivalent this would break the semantics.

    Of course, you can make an ordered view of the set and then hash that, but it would appear to be prohibitively costly - a good reason to not provide it by default.


    As to why forward_list is excluded, I'm not so sure. This looks like simple oversight.