
Daniel James wrote:
Peter Dimov wrote:
Do not give much weight to such char_traits definitions, issue 6.17 notwithstanding. The proposed extensions treat std::string as a container, not as... whatever the other aspect of std::string is supposed to be. That is, the hash value of a string s is defined as the hash value of the range s.begin(), s.end().
If you look at the container requirements table, you'll see that container equality is defined in terms of operator== on the elements.
The (bold enough) author of a string that is not a container can provide an overload of hash_value (in the namespace of the corresponding traits class) with the appropriate semantics.
Well, partly I just feel like I should go along with the current opinion of the standards comittee. But here I do agree with them.
Do not give much weight to the opinion of the committee, either. The resolution of the hash<string> issue follows the path of the least resistance. It's not that other basic_string instances should not have a hash function, it's that defining this function exposes the problems with std::string and unordered_*.
'std::equal_to<std::string>' is defined as using char_traits. And if the hash function doesn't match std::equal_to, then I believe it's broken.
Example of the above. The hash function isn't broken. Using this hash function in combination with std::equal_to is broken. Unfortunately, the unordered containers do not give us a way to replace the default equality relation. shared_ptr and weak_ptr encounter the same problem.
Regardless of whether using char_traits was a bad idea in the first place.
Nobody uses nonstandard character traits. They are fundamentally broken for a variety of reasons. Their only purpose is to generate discussions such as this one. ;-) But if this will make you feel better, define the overload as taking basic_string<Ch, char_traits<Ch>, A>. Nobody will spot the difference.