【发布时间】:2020-06-18 14:46:25
【问题描述】:
我认为大部分工作都在这里完成,最后缺少一点细节。继续阅读。
我正在尝试编写胶水代码,用于使用MurmurHash3 散列 C++ 中 GMP 库的大整数(mpz_t 和 mpz_class)。我这样做是为了以后在std::unordered_map<mpz_class, int> 中使用它们。
我希望代码能够以有用的方式编译 32 位和 64 位系统,并且在需要 128 位系统时易于扩展。为此我编写了MurmurHash3_size_t() 函数,它调用MurmurHash3 的正确哈希函数,然后将结果转换为size_t。我假设size_t 在 32/64/128 位系统方面具有正确的位大小。 (我不知道这个假设是否有用。)这部分代码编译得很好。
当我想定义std::hash 函数时,问题就出现了。我的代码出现编译器错误(请参阅代码中的注释)。如何正确编写这些std::hash函数以及如何调用它们?
文件hash_mpz.cpp:
#include "hash_mpz.h"
#include <gmpxx.h>
#include "MurmurHash3.h"
size_t MurmurHash3_size_t(const void *key, int len, uint32_t seed) {
#if SIZE_MAX==0xffffffff
size_t result;
MurmurHash3_x86_32(key, len, seed, &result);
return result;
#elif SIZE_MAX==0xffffffffffffffff
size_t result[2];
MurmurHash3_x64_128(key, len, seed, &result);
return result[0] ^ result[1];
#else
#error cannot determine correct version of MurmurHash3, because SIZE_MAX is neither 0xffffffff nor 0xffffffffffffffff
#endif
}
namespace std {
size_t hash<mpz_t>::operator()(const mpz_t &x) const {
// found 1846872219 by randomly hitting digits on my keyboard
return MurmurHash3_size_t(x->_mp_d, x->_mp_size * sizeof(mp_limb_t), 1846872219);
}
size_t hash<mpz_class>::operator()(const mpz_class &x) const {
// compiler error in next statement
// error: no matching function for call to ‘std::hash<__mpz_struct [1]>::operator()(mpz_srcptr)’
return hash<mpz_t>::operator()(x.get_mpz_t());
}
}
【问题讨论】:
-
请随意评论目标系统的位大小的确定,因为我不确定什么是最好/最便携的方法。
-
C++ std::hash for GMP's big integer types mpz_class and mpz_t 页面可能会为您提供解决方案。虽然它不使用 murmurhash,但它提供了使用 C++17 的内置数据散列算法
string_view散列mpz_t和mpz_class的代码。
标签: c++ hash unordered-map gmp