web-dev-qa-db-ja.com

unordered_setを使用するにはどうすればよいですか?

私はこのようなunordered_setを定義しようとしています:

unordered_set<Point> m_Points;

コンパイルすると、次のエラーが表示されます。

C++標準では、このタイプのハッシュは提供されていません。

クラスPoint

class Point{
    private:
        int x, y;
    public:
        Point(int a_x, int a_y)
            : x(a_x), y(a_y)
        {}
        ~Point(){}

        int getX()const { return x; }
        int getY()const { return y; }

        bool operator == (const Point& rhs) const{
            return x == rhs.x && y == rhs.y;
        }

        bool operator != (const Point& rhs) const{
            return !(*this == rhs);
        }
};
  • Pointのハッシュ関数をどのように/どこで定義しますか?
  • 2Dポイントに適したハッシュ関数は何でしょうか?
23
brainydexter

std::unordered_setでは、 ハッシュ関数 を記述して、独自の型を保存および検索する必要があります。

std名前空間の基本型と多くの型には、std::hash<Key>内にそのようなハッシュ関数があります。これらの関数は 特定の規則 に従います。

  1. タイプKeyの単一のパラメーターを受け入れます。

  2. パラメーターのハッシュ値を表すタイプsize_tの値を返します。

  3. 呼び出されたときに例外をスローしません。

  4. 等しい2つのパラメーターk1およびk2の場合、std::hash<Key>()(k1) == std::hash<Key>()(k2)

  5. 等しくない2つの異なるパラメータk1k2の場合、std::hash<Key>()(k1) == std::hash<Key>()(k2)が非常に小さく、1.0/std::numeric_limits<size_t>::max()に近づく確率。

定義が邪魔にならないようになったので、ポイント構造に適したハッシュ関数について考えてみましょう。 request があり、std::pair(ポイント構造に非常に似ています)がハッシュ関数を取得しましたが、残念ながら、それはC++ 11標準にはなりませんでした。

しかし、私たちは幸運です:SOは素晴らしいです、そしてもちろん、あなたは基本的にすでに 答えを見つける ができます。std::hashthis answer に従って、ハッシュ関数を詳しく見てみましょう。

namespace std
{
    template <>
    struct hash<Point>
    {
        size_t operator()(Point const & x) const noexcept
        {
            return (
                (51 + std::hash<int>()(x.getX())) * 51
                + std::hash<int>()(x.getY())
            );
        }
    };
}

これで完了です。

24
nijansen