I am teaching myself c++ by doing a series of exercises. I liked the idea of working out how hash tables could be done using just the language and no std calls. I discovered that you cant do "class member function partial template specialisation" and so worked on options for how this would be achieved. The code below is a stripped down version of the useful parts of a hash table. Leaving just enough to show the structure of what is needed.
Is there a better way to construct the class - IE a better idiom to solve partial specialisation?
I have tried full class specialisation and struct partial template specialisation but this seems the best so far.
I would be interested in comments about other ways to call the members and fuctions. I have thought of:
- A 'using' line for all the members/function in the fuctions.
- One 'using' line to create a typedef that can be used as the prefix.
- Putting the full cast at each use.
#include "stdio.h"
template <typename K, typename H>
class hash_table_common {
public:
H& hash_type() // Standard CRTP helper function
{
return static_cast<H&>(*this);
}
int& operator[](K key)
{
return hash_type().get_value(key);
}
size_t hash(int key)
{
return key % 10;
}
int m_storage[10]{ 0 };
};
template <typename K>
class hash_table : public hash_table_common<K, hash_table<K>> {
public:
class hash_table_common<K, hash_table<K>>& hash_type()
{
return static_cast<hash_table_common<K, hash_table<K>>&>(*this);
}
int& get_value(K key)
{
int hashable = 3; // value_to_int(); Real code will go here, for this demo it works for one value!
int index1 = hash_type().hash(hashable);
return hash_type().m_storage[index1];
}
};
template <>
class hash_table<const char*> : public hash_table_common<const char*, hash_table<const char*>> {
public:
class hash_table_common<const char*, hash_table<const char*>>& hash_type()
{
return static_cast<hash_table_common<const char*, hash_table<const char*>>&>(*this);
}
int& get_value(const char* key)
{
int hash_as_int = (int)key[0];
int index = hash_type().hash(hash_as_int);
return hash_type().m_storage[index];
}
};
#endif
int main() {
class hash_table<const char*> a;
class hash_table<float> b;
a["word"] = 3;
b[4.5f] = 14;
printf("%d %d", a["word"], b[4.5f]);
return 0;
}