私はこのような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);
}
};
std::unordered_set
では、 ハッシュ関数 を記述して、独自の型を保存および検索する必要があります。
std
名前空間の基本型と多くの型には、std::hash<Key>
内にそのようなハッシュ関数があります。これらの関数は 特定の規則 に従います。
タイプKey
の単一のパラメーターを受け入れます。
パラメーターのハッシュ値を表すタイプsize_t
の値を返します。
呼び出されたときに例外をスローしません。
等しい2つのパラメーターk1
およびk2
の場合、std::hash<Key>()(k1) == std::hash<Key>()(k2)
。
等しくない2つの異なるパラメータk1
とk2
の場合、std::hash<Key>()(k1) == std::hash<Key>()(k2)
が非常に小さく、1.0/std::numeric_limits<size_t>::max()
に近づく確率。
定義が邪魔にならないようになったので、ポイント構造に適したハッシュ関数について考えてみましょう。 request があり、std::pair
(ポイント構造に非常に似ています)がハッシュ関数を取得しましたが、残念ながら、それはC++ 11標準にはなりませんでした。
しかし、私たちは幸運です:SOは素晴らしいです、そしてもちろん、あなたは基本的にすでに 答えを見つける ができます。std::hash
this 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())
);
}
};
}
これで完了です。