使用 C++11 散列自己的字符串类型
Hashing own String type with C++11
所以我正在尝试使用 clang(使用 libc++)编译一些代码库,但我一直在寻找 libstdc++ 中内部函数的用途。有谁知道使用标准库或 boost/etc 来散列自定义字符串的一些好方法?当然我可以从中制作 std::string,但我不使用特殊字符串制作额外的副本。
namespace std
{
template<>
struct hash<ct::String> : public __hash_base<size_t, ct::String>
{
size_t operator()(const ct::String& __s) const noexcept
{
return std::_Hash_impl::hash(__s.begin(), __s.end() - __s.begin());
}
};
template<>
struct __is_fast_hash<hash<ct::String>> : std::false_type
{ };
}
没有 "standard" 方法可以做到这一点,因为标准库不公开除 std::string
以外的字符串的散列函数。但是,如果你查看 usr/include/c++/x.x.x/tr1/functional_hash.h
,你可以看到他们的字符串哈希实现(我稍微清理了代码)
static std::size_t hash(const char* first, std::size_t length)
{
std::size_t result = static_cast<std::size_t>(2166136261UL);
for (; length > 0; --length)
{
result ^= static_cast<std::size_t>(*first++);
result *= static_cast<std::size_t>(16777619UL);
}
return result;
}
对于 64 位
std::size_t hash(const char* first, std::size_t length)
{
std::size_t result = static_cast<std::size_t>(14695981039346656037ULL);
for (; length > 0; --length)
{
result ^= static_cast<std::size_t>(*first++);
result *= static_cast<std::size_t>(1099511628211ULL);
}
return result;
}
根据您的代码调整它应该很容易。
所以我正在尝试使用 clang(使用 libc++)编译一些代码库,但我一直在寻找 libstdc++ 中内部函数的用途。有谁知道使用标准库或 boost/etc 来散列自定义字符串的一些好方法?当然我可以从中制作 std::string,但我不使用特殊字符串制作额外的副本。
namespace std
{
template<>
struct hash<ct::String> : public __hash_base<size_t, ct::String>
{
size_t operator()(const ct::String& __s) const noexcept
{
return std::_Hash_impl::hash(__s.begin(), __s.end() - __s.begin());
}
};
template<>
struct __is_fast_hash<hash<ct::String>> : std::false_type
{ };
}
没有 "standard" 方法可以做到这一点,因为标准库不公开除 std::string
以外的字符串的散列函数。但是,如果你查看 usr/include/c++/x.x.x/tr1/functional_hash.h
,你可以看到他们的字符串哈希实现(我稍微清理了代码)
static std::size_t hash(const char* first, std::size_t length)
{
std::size_t result = static_cast<std::size_t>(2166136261UL);
for (; length > 0; --length)
{
result ^= static_cast<std::size_t>(*first++);
result *= static_cast<std::size_t>(16777619UL);
}
return result;
}
对于 64 位
std::size_t hash(const char* first, std::size_t length)
{
std::size_t result = static_cast<std::size_t>(14695981039346656037ULL);
for (; length > 0; --length)
{
result ^= static_cast<std::size_t>(*first++);
result *= static_cast<std::size_t>(1099511628211ULL);
}
return result;
}
根据您的代码调整它应该很容易。