2

構造体の一意のリストを維持するために unordered_set を使用しようとしています。構造体 Name のハッシュ関数を定義しましたが、別の構造体メンバー Address を含むように Name 構造体を拡張すると、コンパイル エラーが発生します。Address 構造体をハッシュする方法を指定する必要があることはわかっていますが、どこでどのようにハッシュするかがわかりません。

#include <unordered_set>
#include <string>

using namespace std;

struct Address
{
    int num;
};

struct Name
{
    string first;
    string second;
    Address address;
};


struct hashing_fn {

    size_t operator()(const Address &a ) const
    {
        return  hash<int>()(a.num);
    }

    size_t operator()(const Name &name ) const
    {
        return hash<string>()(name.first) ^ hash<string>()(name.second) ^ hash<Address>()(name.address);
    }
};

int main(int argc, char* argv[])
{
    unordered_set<Name,hashing_fn> ids;
    return 0;
}

アップデート

完了するために、これは修正でした:

template<>
struct hash<typename Address> {
    size_t operator()(const Address &a ) const
    {
        return  hash<int>()(a.num);
    }
};
4

1 に答える 1

2

あなたは決して定義しませんでしたhash<Address>!代わりに、独自の関数を使用する必要がありますoperator()(name.address)


単純なXORingはおそらく最善の解決策ではありません。hash_combine()Boostをコピーして、負荷全体を次のように配置することを強くお勧めしますnamespace std

template <class T>
inline void hash_combine(std::size_t & seed, const T & v)
{
  std::hash<T> hasher;
  seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}

namespace std
{
  template <> struct hash<Address>
  {
    inline size_t operator()(const Address & a) const
    {
      return hash<int>()(a.num);
    }
  };

  template <> struct hash<Name>
  {
    inline size_t operator()(const Name & a) const
    {
      size_t seed = 0;
      hash_combine(seed, name.first);
      hash_combine(seed, name.second);
      hash_combine(seed, name.address);
      return seed;
    }
  };
}

これで、型を直接使用できます(等式コンパレータの実装を条件とします)。std::unordered_set<Name> s;

于 2011-11-30T01:13:26.457 に答える