From e205e1e1a009905585ca37b8e470b5dd83e6215e Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Wed, 13 Aug 2014 04:18:38 +0200 Subject: [PATCH] investigation of hash function extension points (#722) start a systematic research about the coexistence of std::hash and boost::hash. The goal is to build an automatic bridge function -- but this is hampered by the unfortunate standard implementation of std::hash Since meanwhile even the GCC people seem to have realized this wasn't a good idea, I am geared towards using a hack to work around this problem, which can be expected to go away with GCC 4.8.x A possible idea how to construct such a workaround is http://stackoverflow.com/questions/12753997/check-if-type-is-hashable I start this investigation by defining two custom types, each with his own extension point for hashing. The goal would then be to use both in a standard hashtable container. --- research/try.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/research/try.cpp b/research/try.cpp index 9a55000cd..88cfb5a4f 100644 --- a/research/try.cpp +++ b/research/try.cpp @@ -28,24 +28,90 @@ /** @file try.cpp - ** Investigation: how to supply a hash function for custom types + ** Investigation: how to supply a hash function for custom types. + ** This example defines two custom types, each of which provides a way + ** to calculate hash values. But in one case, we use the new \c std::hash + ** as a framework, in the other case we use the extension mechanism for + ** \c boost::hash. The latter has the benefit of being simpler and less verbose + ** to write, since a simple ADL function is sufficient as extension point ** */ //#include #include +#include +#include +#include +#include + +using std::vector; using std::string; using std::cout; using std::endl; +class S + { + string s_; + + friend std::hash; + + public: + S(string ss ="") + : s_(ss) + { } + }; + +namespace std { + template<> + struct hash + { + size_t + operator() (S const& val) const noexcept + { + hash string_hasher; + return string_hasher(val.s_); + } + }; +} + +class V + { + vector v_; + + public: + V(string ss ="") + { + v_.push_back(ss); + } + + friend size_t + hash_value (V const& v) + { + return boost::hash_value(v.v_); + } + }; int main (int, char**) { + string p("Путин"), pp(p); + S s(p), ss(pp); + V v(p), vv(pp); + std::hash std_stringHasher; + boost::hash boo_stringHasher; + + std::hash std_customHasher; + boost::hash boo_customHasher; + + cout << "raw hash(std) = " << std_stringHasher(p) <<"|"<< std_stringHasher(pp) + << " (boost) = " << boo_stringHasher(p) <<"|"<< boo_stringHasher(pp) + << "\n custom hash (std) " << std_customHasher(s) <<"|"<< std_customHasher(ss) + << "\n custom hash (boost) " << boo_customHasher(v) <<"|"<< boo_customHasher(vv) + ; cout << "\n.gulp.\n"; return 0;