I have a hash table class. It has a template parameter hashFunction:
#include <string>
template<class KeyType> using hashFunction_t = size_t(size_t, const KeyType&);
template< class KeyType, class ValueType, int nHashGroups,
hashFunction_t<KeyType> hashFunction >
class HashTable
{
};
class Entity
{
//djb2
size_t stringHash(size_t nGroups, const std::string& key)
{
unsigned long hash = 5381;
const char* str = key.c_str();
int c = 0;
while (c = *str )
hash = ((hash << 5) hash) c;
return hash % nGroups;
}
HashTable <std::string, int, 10, stringHash> ht;
};
int main()
{
Entity{};
}
I would prefer to hide stringHash function inside the Entity class as a private function but doing that gives me an error:
Error (active) E0458 argument of type
"size_t (Entity::*)(size_t nGroups, const std::string &key)"
is incompatible with template parameter of type
"hashFunction_t<std::string> *"
How can I do this?
CodePudding user response:
The problem is that you are trying to use a pointer-to-member as a type template parameter, and this is not supported, basically because when you define a type you don't bind that type to any specific object.
When (as suggested in a comment) you make stringHash static, then you no longer need the object, so it can be used to define the type.
If you still need to have stringHash from a non-static member, then you can change the template to something like the below. Be aware that you have to pass the object to the HashTable in order to call the hashFunction. Also, keep an eye on the syntax to call it.
template<class KeyType, class Obj> using hashFunction_t =
size_t(Obj::*)(size_t, const KeyType&);
template< class KeyType, class ValueType, int nHashGroups,
class Obj, hashFunction_t<KeyType, Obj> hashFunction>
class HashTable
{
public:
explicit HashTable(Obj& obj) : m_obj{obj} {
(m_obj.*hashFunction)(10, ""); // arguments just for illustrative purposes
}
private:
Obj& m_obj; // keep a reference to the object to call the method
// be careful with dangling references
};
class Entity
{
size_t stringHash(size_t nGroups, const std::string& key)
/* ... */
// Pass a reference to the object
HashTable <std::string, int, 10, Entity, &Entity::stringHash> ht{*this};
};
