C++ 在我的例子中,如何重载equal方法,使无序_multimap中的不同对象具有相同的hashcode值

C++ 在我的例子中,如何重载equal方法,使无序_multimap中的不同对象具有相同的hashcode值,c++,hashcode,multimap,C++,Hashcode,Multimap,我写了一张这样的地图: unordered_multimap<Point, int, StrHash, StrCompare> map template <class Map> auto approx_find(Map& map, const Point& point) -> decltype(map.begin()) { decltype(map.end()) it; for (int x_offset = -2; x_offse

我写了一张这样的地图:

unordered_multimap<Point, int, StrHash, StrCompare> map
template <class Map>
auto approx_find(Map& map, const Point& point) -> decltype(map.begin())
{
    decltype(map.end()) it;
    for (int x_offset = -2; x_offset <= 2, ++x_offset)
        for (int y_offset = -2; y_offset <= 2, ++y_offset)
            if (abs(x_offset) + abs(y_offset) < 3 &&
                (it = map.find({point.x + x_offset, point.y + y_offset})) != map.end())
            return it;
    return map.end();
}

这不是散列映射/
无序映射
的工作方式。根据定义,如果散列不相等,则对象不相等。不仅如此,您的“equality”操作符还允许类似于
A(220119)
B(220220)
C(220222)
的操作,其中A==B和B==C,但A!=我看不出有什么办法可以完成你在这个问题上提出的问题,但你是否真的想解决一个问题


根据您的评论,听起来您想要
std::vector
而不是
std::unordered\u map
。然后,您只需使用
std::find
来查找您关心的元素,而不必经过无操作哈希的间接过程。

必须这样说,因为如果您的容错能力允许的话,这会容易得多:您可以将值四舍五入到2或3的最接近倍数


MarkB建议使用
向量
。。。只是为了知识兴趣列出了一些其他的


使用
无序映射
可以获得您想要的功能,但不是很干净:您需要使用代码来编排逻辑以实现近似相等。首先,相等函数必须检查实际相等:

struct PointCompare{
    bool operator()(const Point& a, const Point& b) const {
        return a.x == b.x && a.y == b.y;
    }
};
然后,您将需要这样的支持功能:

unordered_multimap<Point, int, StrHash, StrCompare> map
template <class Map>
auto approx_find(Map& map, const Point& point) -> decltype(map.begin())
{
    decltype(map.end()) it;
    for (int x_offset = -2; x_offset <= 2, ++x_offset)
        for (int y_offset = -2; y_offset <= 2, ++y_offset)
            if (abs(x_offset) + abs(y_offset) < 3 &&
                (it = map.find({point.x + x_offset, point.y + y_offset})) != map.end())
            return it;
    return map.end();
}
总的来说,这是13次查找——或多或少随机地分布在哈希表的存储桶周围,因此对缓存不是特别友好——而不是通常的1次



另一个完全不同的选择是使用
无序的_multimap
来跟踪图的一般区域中的
s-足够近,它们可能满足
,如果在StrHash中我只写“return 1;”,我可以得到我想要的结果,但效率不高。当返回1时,每个对象都有相同的哈希代码1,然后将运行StrCompare(),在StrCompare()中,我将(220119)、B(220220)、C(220222)设置为相同。根据定义,如果散列不相等,则对象不相等。我可以通过重载相等方法更改此定义吗?是的,类似于您所说的,那么我可以通过重载相等方法更改此定义吗?@GKGDTH“我可以更改此定义吗”-否-在
无序映射
操作期间,除非哈希已映射到哈希表中的同一个bucket,否则不会进行相等比较。如果哈希不相等,则对象根据定义是不同的,并且永远不会调用相等运算符。如果希望两个对象比较相等,则它们必须具有相同的哈希代码。可以通过重写hashcode()方法而不是equals()方法来更改对象的哈希代码。请澄清你的问题。
std::unordered_multimap<Point, Point> areas;

Point p = { ...whatever... }; 

// keys for nearby points:
Point around[] = { { (p.x - 2) / 3 * 3, (p.y - 2) / 3 * 3 }, 
                   { (p.x + 2) / 3 * 3, (p.y - 2) / 3 * 3 },
                   { (p.x - 2) / 3 * 3, (p.y + 2) / 3 * 3 },
                   { (p.x + 2) / 3 * 3, (p.y + 2) / 3 * 3 } };