1

要准备在 中使用的结构unordered_set,需要散列函数。这可以通过重载operator size_t()(ew)或烦人的方式来完成,如下所示:

namespace std
{
 template<> struct hash<MyStruct> : public unary_function<MyStruct, size_t>
 {
  size_t operator()(const MyStruct& mystruct) const
  {
   return 0; //hash here
  }
 };
}

有没有办法创建这样的接口:

struct Hashable
{
 virtual size_t hash() = 0;
};

并设置std::hash为适用于它的任何实现?我很确定模板不能那样工作,所以这让我陷入了困境。是否有一个安全的 size_t 成语可以像安全的 bool 成语一样工作,用于转换为 size_t?或者是其他东西?std::hash当每个结构中的公共接口和成员函数更方便时,为每个结构编写新的特化是愚蠢的。

4

2 回答 2

4

其实还有另一种解决方案:

template <typename T>
struct Hashable {
    size_t operator()(T const& t) { return hash_value(t); }
};

template <typename T, typename E = std::equal<T>, typename A = std::allocator<T>>
using MySet = std::unordered_set<T, Hashable<T>, E, A>;

现在,您所要做的就是定义一个hash_value接受TorT const&作为参数并返回 a的自由函数size_t

编辑:更改hashhash_value,就像在 Boost 中一样。

于 2012-11-01T17:55:11.167 回答
3

每个结构中的通用接口和成员函数会方便得多。

它不会。std::hash您现在不必处理散列,而是必须用这个细节来打扰每个类/结构每个接口。你必须经常处理“我的一些同事删除了一个”。等不会更好。情况会更糟。Hashable

您可以通过 SFINAE 的部分专业化来实现它。

于 2012-11-01T17:51:40.867 回答