我喜欢这个 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;
}
最佳答案
您不能将它与 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
,但大小必须已知)。
我根据允许编译时和运行时字符串的链接问题的原始实现写了一个答案:
关于c++ - 在运行时使用模板化的 constexpr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48923259/