Как правило, да, вам нужно, чтобы клиент указывал хеш-функцию, поскольку, если вы пишете универсальную хеш-таблицу и работаете с произвольным типом T, вы не можете знать, как ее хешировать таким образом, чтобы семантически значимый. Вы можете сделать это путем параметризации класса как по типу хранимых элементов, так и по хеш-функции. Например:
template <typename T, typename Hash = std::hash<T>>
class MyHashTable {
/* ... */
}
Здесь вы можете использовать аргументы по умолчанию с шаблонами, чтобы выбрать хеш-функцию по умолчанию, если пользователь не укажет иное.
Хотя клиент обычно может указывать начальный размер таблицы, это не обязательно. Вы можете сделать обоснованное предположение о количестве сегментов (скажем, сначала использовать 17 сегментов), увеличивая таблицу по мере увеличения коэффициента загрузки. Это похоже, скажем, на то, как работает std::vector
: реализация может выбрать размер по умолчанию, но если клиент явно запрашивает предварительно заданный вектор или вызывает reserve
, реализация получает подсказку от пользователя. Например, вы можете иметь конструктор вида
template <typename T, typename Hash = std::hash<T>>
class MyHashTable {
public:
MyHashTable(unsigned numBuckets = 17);
}
Таким образом, клиент может просто создать хеш-таблицу с количеством сегментов по умолчанию или, если у них есть представление о количестве сегментов, которые он хотел бы, он может указать в качестве параметра. Тем не менее, вы можете также захотеть скрыть сегменты как подробности и просто указать клиенту, сколько элементов они ожидают поместить в таблицу, а затем попросите ваш класс выполнить закулисные вычисления для этого. Это облегчает переключение реализаций за кулисы, так что если вы хотите использовать что-то вроде динамической совершенной хеш-таблицы вместо цепного хеширования, класс может справиться со сложностью вычисления начального размера.
Что касается примеров кода, я не уверен, как их предоставить, не отказываясь от множества сложностей, связанных с созданием хеш-таблицы. :-) Если есть определенный фрагмент кода, который вас интересует и у вас проблемы с написанием самостоятельно, не стесняйтесь опубликовать его как отдельный вопрос, чтобы вы могли получить более целенаправленную обратную связь.
Надеюсь, это поможет!