Search code examples
c++function-pointersfunction-prototypes

How to declare a templated function so that can be passed in a class constructor/function


I want to pass in a user defined function to a class which requires a user defined matching function. In ye olde days of C I would have used a function pointer with void* arguments. But there must be a better way...

Here is roughly the sort of thing I want to do. One limitation I have is that the platform I am on has no standard library. But the basic core language C++11 is available.

What I need to do:

#include <iostream>

using namespace std;

// TODO - replace this C construct with C++ equivalent
//typedef bool(*match_key)(const void* key1, const void* key2);

// somehow declare this as a typedef?  need a way to declare a signature in C++
typedef template<class T>
bool (*match_key)(const T& key1, const T& key2);


// *** User defined matching function
bool mymatcher(const int i, const int j) {
    return i == j;
}

template<class K>
class hashmap {
public:
    hashmap<K>(const K& key, match_key matchfunc) : key_(key), cmp(matchfunc) { }

    bool matched(const K& key) {
        return cmp(key_, key);
    }

private:
    const K key_;
    match_key cmp;
};


int main()
{
    int i = 3;
    int j = 4;

    hashmap<int> hm(i, mymatcher);
    cout << "i matches j? " << (hm.matched(j) ? "yes" : "no") << endl;

    return 0;
}

Solution

  • #include <iostream>
    
    using namespace std;
    
    // TODO - replace this C construct with C++ equivalent
    //typedef bool(*match_key)(const void* key1, const void* key2);
    
    // somehow declare this as a typedef?  need a way to declare a signature in C++
    typedef template<class T>
    using match_key = bool (*)(const T& key1, const T& key2);
    
    
    // *** User defined matching function
    bool mymatcher(const int i, const int j) {
        return i == j;
    }
    
    template<class K>
    class hashmap{
    public:
        hashmap(const K& key, match_key<K> matchfunc) : key_(key), cmp(matchfunc) { }
    
        bool matched(const K& key) {
            return cmp(key_, key);
        }
    
    private:
        const K key_;
        match_key<K> cmp;
    };
    
    
    int main()
    {
        int i = 3;
        int j = 4;
    
        hashmap<int> hm(i, mymatcher);
        cout << "i matches j? " << (hm.matched(j) ? "yes" : "no") << endl;
    
        return 0;
    }