Ответ 1
Эта ошибка не связана с шаблонами. Это множественное определение функции. Я думаю, вы определили strSimpleHash
в заголовке без использования inline
(вы не добавили код, где вы определяете эту функцию).
В ваших комментариях вы попросили использовать HashTable
следующим образом:
HashTable<std::string, int> // (ie, without passing the 3rd argument)
Это невозможно. Хотя вы можете указать значение по умолчанию для аргумента шаблона (но не в специализации), например:
template<int n = 0> struct dummy {};
dummy<> obj;
в вашем случае вы не можете этого сделать, потому что общий случай вашего шаблона не принимает только функции типа long(std::string)
.
Однако это можно обойти это, назначив функцию по умолчанию для каждого возможного типа. Обратите внимание, что вы должны использовать указатель на функцию, так как код немного понятнее:
// A C++03-style template typedef
template<typename K>
struct HashFunc
{
typedef long (*type)(K);
};
// The default value. Defined only for some cases,
// compile error for not handled cases
template<typename K>
struct DefaultHash;
template<>
struct DefaultHash<std::string>
{
// Static constant pointer-to-function, pointing to the hash func.
static constexpr HashFunc<std::string>::type func = &strSimpleHash;
};
// The HashTable class
template <class K, class V, typename HashFunc<K>::type H = DefaultHash<K>::func>
class HashTable
{
};
template <class V>
class HashTable<std::string, V, strSimpleHash>
{
};
И тогда вы можете использовать его так, как вы хотели, опустив третий параметр шаблона. Обратите внимание, что этот код компилируется на gcc, но не на clang, (На самом деле, я не уверен, какой компилятор прав...)