Search code examples
c++hashtablefunction-pointersmember-initialization

Hash Table not accepting function passed into constructor in member init list


I have a hash table template that I have written for a class. I have a project due that relies on utilizing this hash table. It accepts an unsigned integer value to initialize the number of buckets it has, as well as a hash function to point to. I have not written that hash function yet, but I have a declaration for it. When I try to use the member initializer in my Game class for the hash table data member, it gives me an error that I don't understand.

Error 1 error C3867: 'Game::xorHash': function call missing argument list; use '&Game::xorHash' to create a pointer to member

2 IntelliSense: no instance of constructor "HTable<Type>::HTable [with Type=std::string]" matches the argument list
        argument types are: (int, unsigned int (const std::string &s))

my Hash Table class is as follows:

#pragma once
#include "SLList.h"

template<typename Type> class HTable
{
public:
    HTable(unsigned int numOfBuckets, unsigned int (*hFunction) (const Type &v));
    ~HTable();
    HTable<Type>& operator=(const HTable<Type>& that);
    HTable(const HTable<Type>& that);
    void insert(const Type& v);
    bool findAndRemove(const Type& v);
    void clear();
    int find(const Type& v) const;

private:
    SLList<Type>* ht;
    unsigned int (*hFunct) (const Type &v);
    unsigned int numOfBuck;
};

template<typename Type>
HTable<Type>::HTable(unsigned int numOfBuckets, unsigned int (*hFunction) (const Type     &v))
{
    ht = new SLList<Type>[numOfBuckets];
    this->numOfBuck = numOfBuckets;
    this->hFunct = hFunction;
}

template<typename Type>
HTable<Type>::~HTable()
{
    delete [] ht;
    ht = nullptr;
}  

template<typename Type>
HTable<Type>& HTable<Type>::operator=(const HTable<Type>& that)
{
    if(this != &that)
    {
        delete [] this->ht;
        this->hFunct = that.hFunct;
        this->numOfBuck = that.numOfBuck;
        this->ht = new SLList<Type>[numOfBuck];
        for(unsigned int i = 0; i < this->numOfBuck; i++)
            this->ht[i] = that.ht[i];
    }
    return *this;
}  

template<typename Type>
HTable<Type>::HTable(const HTable<Type>& that)
{
    this = *that;
}

template<typename Type>
void HTable<Type>::insert(const Type& v)
{
    ht[hFunct(v)].addHead(v);
}

template<typename Type>
bool HTable<Type>::findAndRemove(const Type& v)
{
    SLLIter<Type> iter(ht[hFunct(v)]);
    for(iter.begin(); !iter.end(); ++iter)
    {
        if(v == iter.current())
        {
            ht[hFunct(v)].remove(iter);
            return true;
        }
    }
    return false;
} 

template<typename Type>
void HTable<Type>::clear()
{
    for(unsigned int i = 0; i < this->numOfBuck; ++i)
        ht[i].clear();
}

template<typename Type>
int HTable<Type>::find(const Type& v) const
{
    SLLIter<Type> iter(ht[hFunct(v)]);
    for(iter.begin(); !iter.end(); ++iter)
    {
        if(v == iter.current())
            return hFunct(v);
    }

    return -1;
}

My Game.h:

#pragma once

#include "stdafx.h"
#include "HTable.h"
#include "BST.h"
#include "DTSTimer.h"

using namespace std;

class Game
{
public:
    Game(void);
    virtual ~Game(void);
    void refresh();
    void input();
    unsigned int xorHash(const string &s);

private:
    string userInput;
    DTSTimer timer;
    BST<string> answers;
    HTable<string> dictionary;
};

My Game.cpp (this is obviously just a skeleton, since I can't get the member init to work)

 #include "Game.h"


Game::Game(void) : dictionary(2048, xorHash)
{

}


Game::~Game(void)
{

}

void Game::refresh()
{

}

void Game::input()
{

}

unsigned int Game::xorHash(const string &s)
{
    return 0;
}

I've been working on this for a good while, and have been hitting a wall. I would really appreciate some help on how to get this thing up and running. Let me know if there is another snippet that needs to be seen (I've tried to be thorough in that regard).


Solution

  • You have two problems. The first is that you don't pass the member function pointer properly (the error message tells you exactly what do do). The other problem is that a function pointer is not the same as a member function pointer.

    A member function pointer needs an instance object object to call the member function on. And this instance is passed as a hidden first argument, something that normal functions don't have.

    For this you might instead turn to std::function and std::bind:

    class HTable
    {
    public:
        HTable(unsigned int numOfBuckets, std::function<unsigned int(const Type&)> hFunction);
        ...
    
    private:
        std::function<unsigned int(const Type&)> hFunct;
        ...
    };
    

    Then

    Game::Game(void) : dictionary(2048, std::bind(&Game::xorHash, this))
    {
    }