Home > database >  Unordered map hash function
Unordered map hash function

Time:11-17

#include <iostream>
#include <unordered_map>
#include <utility>
#include <cmath>
#include <stdint.h>

template <class T>
struct Vec2 
{
    T x, y;
    Vec2()           : x(0) , y(0)  { };
    Vec2(T xn, T yn) : x(xn), y(yn) { };

    bool operator==(const Vec2& vec) const 
    {
        return (x == vec.x) and (y == vec.y); 
    }
};

struct HashVec2int
{
    const uint32_t maximum;

    // HashVec2int(const uint32_t& m) : maximum(m) { }

    std::size_t operator()(const Vec2<int>& vec) const
    { return (vec.x * maximum)   vec.y; }

};

int main() {

    typedef Vec2<int> iVec2;
    std::unordered_map<std::pair<iVec2, iVec2>, 
                       float, HashVec2int{300}> umap;

    umap[std::make_pair(iVec2(1, 2), iVec2(2, 3))] = 3.14f;
    
    std::cout << umap[std::make_pair(iVec2(1, 2), iVec2(2, 3))];
    
    return 0;
}

I want to initialize a hash function with a maximum x value to hash my implementation of vector.

I changed the struct to a class a couple of times and even marked maximum manually inside of HashVec2int. It gave me cryptic errors.

.\main.cpp:35:32: error: type/value mismatch at argument 3 in template parameter list for 'template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> class std::unordered_map'
         float, HashVec2int{300}> umap;
                                ^
.\main.cpp:35:32: note:   expected a type, got 'HashVec2int{300u}'
.\main.cpp:37:6: error: no match for 'operator[]' (operand types are 'int' and 'std::pair<Vec2<int>, Vec2<int> >')
  umap[std::make_pair(iVec2(1, 2), iVec2(2, 3))] = 3.14f;
      ^
.\main.cpp:39:19: error: no match for 'operator[]' (operand types are 'int' and 'std::pair<Vec2<int>, Vec2<int> >')
  std::cout << umap[std::make_pair(iVec2(1, 2), iVec2(2, 3))];
                   ^

I followed cppreference tutorials on how to create a modified hash function.

CodePudding user response:

You have a map with keys of pairs of iVecs but your hash is for single iVecs, that doesnt match. Though this will only be the next error you will be getting after fixing the current one.

It seems you try to pass an instance HashVec2int{300} as template argument when a type is expected.

If maximum does not change (it should not for the hash to be consistent) you can do it like this:

template <uint32_t maximum>
struct HashVec2int
{
   std::size_t operator()(const Vec2<int>& vec) const
    { return (vec.x * maximum)   vec.y; }

};

int main() {

    typedef Vec2<int> iVec2;
    std::unordered_map<iVec2,
                       float, HashVec2int<200>> umap;

    umap[iVec2(1, 2)] = 3.14f;
    
    std::cout << umap[iVec2(1, 2)];
    
    return 0;
}

If you do not want to make HashVec2int a template you can still use it, then use its type Hashvec2Int as argument for the unordered map template and pass an instance, eg HashVec2Int{200}, to one of the constructors that takes a hash instance: https://en.cppreference.com/w/cpp/container/unordered_map/unordered_map

  • Related