Home > Net >  c : How to pass a normal c function as hash functor for unordered_map
c : How to pass a normal c function as hash functor for unordered_map

Time:09-01

I've got this hash function is C style:

static size_t Wang_Jenkins_hash(size_t h) {
    h  = (h << 15) ^ 0xffffcd7d;
    h ^= (h >> 10);
    h  = (h << 3);
    h ^= (h >> 6);
    h  = (h << 2)   (h << 14);
    return h ^ (h >> 16);
}

Then I try to use it for unordered_map's hash parameter. Do I always need to write a c functor as a wrapper inorder to use it? Or is there a more convenient ways to pass it as template parameter?

Thanks!

CodePudding user response:

Functors are probably the easiest way to do this. When you use a free function the syntax becomes

std::unordered_map<std::size_t, std::size_t, decltype(&Wang_Jenkins_hash)>

but that is only half of what you need. Since we are using a function pointer type we need to pass to the map the function to use, and to do that you have to specify how many initial buckets you want along with the function to actually use. That could be done like

std::unordered_map<std::size_t, std::size_t, decltype(&Wang_Jenkins_hash)> foo(1024, &Wang_Jenkins_hash);

If you instead switch to a functor then code can be changed to

struct Wang_Jenkins_hash
{
    std::size_t operator()(std::size_t h) noexcept const
    {
        h  = (h << 15) ^ 0xffffcd7d;
        h ^= (h >> 10);
        h  = (h << 3);
        h ^= (h >> 6);
        h  = (h << 2)   (h << 14);
        return h ^ (h >> 16);
    }
};

std::unordered_map<std::size_t, std::size_t, Wang_Jenkins_hash> foo;

If you can use C 20 or newer then you can wrap the fucntion in a lambda to use with the map like

auto my_hash = [](auto val) { return Wang_Jenkins_hash(val); };
std::unordered_map<std::size_t, std::size_t, decltype(my_hash)> foo;

CodePudding user response:

Yes, it's possible

#include <iostream>
#include <unordered_map>

size_t Wang_Jenkins_hash(size_t h) {
    h  = (h << 15) ^ 0xffffcd7d;
    h ^= (h >> 10);
    h  = (h << 3);
    h ^= (h >> 6);
    h  = (h << 2)   (h << 14);
    return h ^ (h >> 16);
}

int main() {
    std::unordered_map<size_t, size_t, decltype(&Wang_Jenkins_hash)> m(0, &Wang_Jenkins_hash); 
    return 0;
}
  • Related