Syntax for declaring/initializing JUCE HashMap with custom generateHash() function

Hi all, I reached this point in an older thread, and I hope it’s alright that I start a new thread now that the title no longer really reflects what the questions I have are about.

Here’s the short and long of it:

I need to convert from a pair of integers to another pair of integers, depending on a mapping read in from a file. The JUCE HashMap class seemed perfect for this:

https://docs.juce.com/master/classHashMap.html

I created a simple bag class “TwoInts” to hold the pairs of ints that will be used for both the keys and values, and understandably I need to supply my own hash function for that class:

The types of the key and value objects are set as template parameters. You can also specify a class to supply a hash function that converts a key value into an hashed integer. This class must have the form:

struct MyHashGenerator
{
    int generateHash (MyKeyType key, int upperLimit) const
    {
        // The function must return a value 0 <= x < upperLimit
        return someFunctionOfMyKeyType (key) % upperLimit;
    }
};

I’ve created that class like this:

struct MyHashGenerator
{
    int generateHash (TwoInts key, int upperLimit) const
    {
        String toHash;
        toHash+=String(key.getFirst());
        toHash+=String(key.getSecond());
        return juce::DefaultHashFunctions::generateHash (toHash,upperLimit);
    }
};

I’m now having trouble figuring out the syntax for declaring and initializing the HashMaps, though.

The documentation shows the template as

template<typename KeyType, typename ValueType, class HashFunctionType = DefaultHashFunctions, class TypeOfCriticalSectionToUse = DummyCriticalSection>

and it shows the constructor as

HashMap (int numberOfSlots=defaultHashTableSize, HashFunctionType hashFunction=HashFunctionType())

My best guess was to declare like this:

HashMap<TwoInts,TwoInts,MyHashGenerator> translator;

and then initialize like this:

:translator(1152, MyHashGenerator::generateHash())

But this semi-educated guess results in an error. (no matching function for call to ‘RelayerMApper:MyHashGenerator::generateHash()’)

Can someone show/explain the syntax I should be using here? Or does anyone know where I can find some example code of the JUCE HashMap class being used with a custom key class and corresponding hash function?

(I did get some suggestions in the previous thread to use nested std::unordered_maps which should work with the default hash functions, but I’d really like to use this as a learning opportunity, since I’m learning C++ as I go here, and it would be nice to be familiar with this syntax. If that doesn’t work out, I’ll certainly give the unordered_maps a shot.)

Thanks very much for any help!

Here’s the whole header file I have going, for reference:

#pragma once
#include "JuceHeader.h"
class RelayerMapper
{
    public:
    class TwoInts
        {
            public:
                TwoInts(){}
                TwoInts(int a, int b)
                {
                    first=a;
                    second=b;
                }
                int getFirst()
                {
                    return first;
                }
                int getSecond()
                {
                    return second;
                }
                void setFirst(int in)
                {
                    first=in;
                }
                void setSecond(int in)
                {
                    second=in;
                }
            private:
            int first, second;
        };
        struct MyHashGenerator
        {
            int generateHash (TwoInts key, int upperLimit) const
            {
                String toHash;
                toHash+=String(key.getFirst());
                toHash+=String(key.getSecond());
                return juce::DefaultHashFunctions::generateHash (toHash,upperLimit);
            }
        };
        RelayerMapper()
        :       dtMidiToCoords(1152, MyHashGenerator::generateHash()),
                coordsToDtMidi(1872, MyHashGenerator::generateHash()),
                axisToCoords(98)
        {}

        TwoInts MapDtMidiToCoords(TwoInts twoIntsIn, HashMap<TwoInts,TwoInts> hashmap)
        {
            return hashmap.getReference(twoIntsIn);
        }

    private:
    HashMap<TwoInts,TwoInts,MyHashGenerator> dtMidiToCoords;
    HashMap<TwoInts,TwoInts,MyHashGenerator> coordsToDtMidi;
    HashMap<int,TwoInts> axisToCoords;
};