为 C++ 无序容器哈希支持重载 ObjC 结构

Overloading ObjC struct for C++ unordered containers hash support

我已经创建了 std::unordered_map<CGPoint, unsigned int>,显然,要让它工作,我应该为它编写哈希函数:

namespace std {
    template<> struct hash<CGPoint> {
        inline size_t operator()(const CGPoint & v) const {
            size_t seed = 0;
            ::hash_combine(seed, v.x);
            ::hash_combine(seed, v.y);
            return seed;
        }
    };
};

但是编译不了,我发现有一个地方,应该定义相等运算符。所以我将以下代码写入模板结构。

friend bool operator==(const CGPoint& p1, const CGPoint& p2) {
    return (p1.x == p2.x) && (p1.y == p2.y);
}

但它一直抛出异常:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/functional:659:21: Invalid operands to binary expression ('const CGPoint' and 'const CGPoint')

并且:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/__hash_table:1993:32: No matching function for call to object of type 'key_equal' (aka 'std::__1::__unordered_map_equal, std::__1::equal_to, true>')

很可能我遗漏了一些非常简单的东西,但正如通常发生的那样,我无法理解。提前致谢。

operator==应该是顶级函数,不是友元函数。

以下将编译:

namespace std {
    template<> struct hash<CGPoint> {
        inline size_t operator()(const CGPoint & v) const {
            size_t seed = 0;
            ::hash_combine(seed, v.x);
            ::hash_combine(seed, v.y);
            return seed;
        }
    };
};

bool operator==(const CGPoint& p1, const CGPoint& p2) {
    return (p1.x == p2.x) && (p1.y == p2.y);
}

int main() {
    std::unordered_map<CGPoint, unsigned int> map;
    map[CGPointMake(1, 1)] = 1;
    return 0;
}