C++ 在运行时使用模板化的constexpr

C++ 在运行时使用模板化的constexpr,c++,constexpr,C++,Constexpr,我喜欢这个crc32实现: 它在编译时运行良好: ctcrc32("StackOverflow"); 但是否可以在运行时使用它: void myfunction(const std::string& str) { uint32_t hash = ctcrc32(str); // ... } 到目前为止,我不得不重写另一个运行时函数,但更愿意只使用一个 编辑 我试过了 ctcrc32(str.c_str()) 但它不起作用**不匹配的类型“const char[len]”和

我喜欢这个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,则无法将其与std::string一起使用。如果您查看主功能:

template <size_t len>
constexpr uint32_t ctcrc32(const char (&str)[len]) {
  return detail::crc32<len - 2>(str) ^ 0xFFFFFFFF;
}
…您可以看到,它在编译时需要字符串的长度,因为它将其用作模板参数detail::crc32

ctcrc32只适用于编译时大小已知的字符数组,它们不必是const或constexpr,但大小必须已知

我根据链接问题的原始实现编写了一个答案,它同时允许编译时和运行时字符串:


我做了,但可能我遗漏了什么:ctcrc32str.c_str显然不能工作不匹配的类型“const char[len]”和“const char*”。它似乎需要一个编译时长度,应该适用于char foo[]=aasdf;ctcrc32foo;。请将错误消息添加到您的问题CHAR foo[]=aasdf;ctcrc32foo;将在编译时解决,我已经以这种方式使用了constexpr。我希望在运行时为dynamic stringI使用相同的函数。我添加了一个基于@CygnusX11的链接问题的答案,允许它在编译时和运行时使用运行时字符串,同时仍然符合C++11标准&mdash;我只是简单地将模板参数移动到函数参数。实现得不错,我的方向不好。谢谢