我正在尝试定义这样的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);
}
};
答案 0 :(得分:24)
std::unordered_set
要求您编写hash functions来存储和查找自己的类型。
std
命名空间中的基类型和许多类型在std::hash<Key>
中都有这样的哈希函数。这些函数遵循certain rules:
接受Key
类型的单个参数。
返回类型size_t
的值,表示参数的哈希值。
调用时不会抛出异常。
对于两个相等的参数k1
和k2
std::hash<Key>()(k1) == std::hash<Key>()(k2)
。
对于不相等的两个不同参数k1
和k2
,std::hash<Key>()(k1) == std::hash<Key>()(k2)
应该非常小,接近1.0/std::numeric_limits<size_t>::max()
的概率。
既然我们已经完成了定义,那么让我们考虑一下你的点结构会有什么好的哈希函数。有一个request std::pair
(它与点结构非常相似)得到了一个哈希函数,但不幸的是,它没有进入C ++ 11标准。
但我们很幸运:太棒了,当然,你基本上已经find the answer了。请注意,您不必自己散列整数,因为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())
);
}
};
}
我们已经完成了。