martinus / robin-hood-hashing

Fast & memory efficient hashtable based on robin hood hashing for C++11/14/17/20
https://gitter.im/martinus/robin-hood-hashing
MIT License
1.5k stars 142 forks source link

`is_transparent` is not working #86

Open bredelings opened 3 years ago

bredelings commented 3 years ago

Hi,

I tried using robin_hood::unordered_map, and its really nice! However, I tried using the is_transparent interface, and it almost works, but does not quite work: It looks like this is because you are putting std::hash into a wrapper.

I defined std::hash to accept a type BUILD_args_ref in addition to the keytype BUILD_args. This all works OK, except that robin_hood::hash doesn't accept my extra hashkey type! You can see this here:

../../source/otc/robin_hood.h:1322:39: error: cannot convert ‘const BUILD_args_ref’ to ‘const BUILD_args&’
 1322 |         *idx = Mix{}(WHash::operator()(key));
      |                      ~~~~~~~~~~~~~~~~~^~~~~

I made a quick hack that fixed this:

// A thin wrapper around std::hash, performing an additional simple mixing step of the result.
template <typename T>
struct hash : public std::hash<T> {

    size_t operator()(T const& obj) const
        noexcept(noexcept(std::declval<std::hash<T>>().operator()(std::declval<T const&>()))) {
        // call base hash
        auto result = std::hash<T>::operator()(obj);
        // return mixed of that, to be save against identity has
        return hash_int(static_cast<uint64_t>(result));
    }

    template <typename K>
    size_t operator()(K const& obj) const
        noexcept(noexcept(std::declval<std::hash<T>>().operator()(std::declval<K const&>()))) {
        // call base hash
        auto result = std::hash<T>::operator()(obj);
        // return mixed of that, to be save against identity has
        return hash_int(static_cast<uint64_t>(result));
    }
};

I am not sure if this is sufficiently careful, but it seems to work.

martinus commented 3 years ago

Hi, thanks for finding! I'll see what I can do, but I unfortunately currently don't have much time for this project