0
#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.

3
  • HashVec2int{300} is not a type, thats what the error message tries to tell you Commented Nov 17, 2022 at 10:01
  • You also need to decide just what you're actually hashing. Your container uses std::pair<Viec2,iVec2> as the keys, but your hasher is hashing just iVec2, not std::pair<iVec2,iVec2> . Whatever guide you were following, you deviated pretty far out. Commented Nov 17, 2022 at 10:04
  • Your attempt to make hasher for type is not very good, but if you really want to go this way you can use template to parametrize your type. Commented Nov 17, 2022 at 10:04

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

3 Comments

That gave me a lot of insight. Thank you!
How would I go about declaring umap in a header file? Should I use HashVec2int<uint_32>? It gives me errors about contradictive constant type 'uint32' and type 'constant uint32'.
@gournge I cannot comment on errors in code I cannot see. Anyhow if you have a new question about a different error you can post a new question

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.