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を受け入れて、を返すフリー関数を定義することだけです。TT const&size_t

編集: Boostの場合と同様に、に変更さhashれました。hash_value

于 2012-11-01T17:55:11.167 に答える
3

各構造体の共通インターフェースとメンバー関数の方がはるかに便利です。

そうではないでしょう。ハッシュを処理する代わりに、すべてのクラス/構造体のすべてのインターフェースをこの詳細でstd::hash煩わせる必要があります。あなたは常に「私の同僚の何人かが削除した」に対処しなければならないでしょう。など。それは良くないでしょう。それはずっと悪いでしょう。Hashable

SFINAEを部分的に特殊化することで、おそらくそれを達成できます。

于 2012-11-01T17:51:40.867 に答える