我喜欢这个crc32实现:CygnusX1 CRC32
它在编译时运行良好:
ctcrc32("StackOverflow");
但是可以在运行时使用它吗?
void myfunction(const std::string& str)
{
uint32_t hash = ctcrc32(str);
// ...
}
到目前为止,我不得不重写另一个(运行时)函数,但更愿意只使用一个。
修改的
我确实尝试了
ctcrc32(str.c_str())
但它不起作用(**不匹配的类型'const char [len]'和'const char *'**)。它似乎需要编译时长度。
以下是实施:
namespace detail {
// CRC32 Table (zlib polynomial)
static constexpr uint32_t crc_table[256] = { 0x00000000L, 0x77073096L, ... }
template<size_t idx>
constexpr uint32_t combine_crc32(const char * str, uint32_t part) {
return (part >> 8) ^ crc_table[(part ^ str[idx]) & 0x000000FF];
}
template<size_t idx>
constexpr uint32_t crc32(const char * str) {
return combine_crc32<idx>(str, crc32<idx - 1>(str));
}
// This is the stop-recursion function
template<>
constexpr uint32_t crc32<size_t(-1)>(const char * str) {
return 0xFFFFFFFF;
}
} //namespace detail
template <size_t len>
constexpr uint32_t ctcrc32(const char (&str)[len]) {
return detail::crc32<len - 2>(str) ^ 0xFFFFFFFF;
}
答案 0 :(得分:1)
如果不重写std::string
,则无法使用它。如果你看一下主要功能:
template <size_t len>
constexpr uint32_t ctcrc32(const char (&str)[len]) {
return detail::crc32<len - 2>(str) ^ 0xFFFFFFFF;
}
...你看到它在编译时需要字符串的长度,因为它将它用作模板参数(detail::crc32<len - 2>
)。
ctcrc32
仅适用于在编译时已知大小的字符数组(它们不必是const
或constexpr
,但必须知道大小)
我根据原始实现写了一个答案,链接问题允许编译时和运行时字符串: