【问题标题】:How to build hash function for various template types?如何为各种模板类型构建哈希函数?
【发布时间】:2016-04-06 10:30:35
【问题描述】:

我正在练习使用template 构建一个可以接受不同类型的哈希表。

如何在编译时不知道类型的情况下实现hashFunction

template<class K, class V>
class HashTable {
  public:
  vector<vector<Bucket<K, V> > > table;
  ...
  size_t hashFunction(const K &k) {
    //can't implement without knowing the runtime types
  }
}

我猜我应该做类似的事情:

return hash<K>(k) % table.size();

更新:

感谢 R Sahu 的回答,现在我知道这是我不清楚的模板部分专业化部分。请参阅this 问题和this link 以供参考。

【问题讨论】:

  • 我认为您(或至少是编译器)确实知道 compile 时的类型。除非您有办法在运行时根据其typeid 查看类型的大小,否则您无能为力。请注意,对于HashTable 的每个实例化,编译器确切地知道K 的类型。

标签: c++ templates hashtable


【解决方案1】:

如何在编译时不知道类型的情况下实现hashFunction

您可以使用通用逻辑为所有类型生成哈希值。将构成 k 的字节视为字符串中的字符。

同时,让用户能够提供自己的哈希函数。

// Generic implementation
template <typename K> struct Hash
{
   static size_t get(const K& k)
   {
      ...
   }
};

template<class K, class V, typename HashGenerator = Hash<K>>
class HashTable {
  public:
  vector<vector<Bucket<K, V> > > table;
  ...
  size_t hashFunction(const K &k) {
     HashGenerator::get(k);
  }
}

struct Foo { ... };

// Specialize Hash for Foo.
template <> struct Hash<Foo>
{
   static size_t get(const Foo& foo)
   {
      ...
   }
}

【讨论】:

  • 感谢您的快速回复。我假设HashGenerator 只是Hash&lt;K&gt; 的别名,只需class Hash&lt;K&gt; 也可以。
  • @LihsingChen,使用HashGenerator 作为默认参数允许您在创建HashTable 时使用与Hash 无关的完全不同的类作为模板参数。
  • 啊,我现在看到了好处。谢谢,很好的答案。
  • “可用于为所有类型生成哈希值的通用逻辑。将组成 k 的字节视为字符串中的字符。” - 只需对于并非所有位都有助于值表示的类型,或者由于例如,等价性更复杂的类型,请注意一点不区分大小写的比较。
  • 我认为这仅对 POD 类型有效。 (通用的Hash 可以static_assert(std::is_pod&lt;T&gt;::value, "not POD") 这个。)就像@TonyD 说的那样,即使在那里你也可能会对填充字节等感到意外。我认为标准库不为用户定义的类型提供通用哈希是有原因的。
猜你喜欢
  • 2018-09-04
  • 1970-01-01
  • 1970-01-01
  • 2021-11-02
  • 1970-01-01
  • 2015-10-05
  • 1970-01-01
  • 2011-02-27
  • 2021-05-31
相关资源
最近更新 更多