如何在C++中的编译时枚举常量数组



我正试图在COMPILE TIME从文字字符串(字符数组(生成一个哈希。例如:

unsigned long long compiledHash = ComputeHash("literal string");

我目前一直在寻找一种方法来枚举字符串中的所有字符,并创建一个唯一的哈希。如果我像往常一样使用for循环,编译器将不会在编译时生成哈希,这不是我想要的。

我可能找到了这样做的方法,但编译器在计算哈希时陷入了无限循环。

template <size_t _length, typename T, int n> struct CostructHash {
unsigned long long Value;
constexpr __forceinline CostructHash(const T(&str)[_length]) :
Value(str[n] ^ n + (n > 0 ? CostructHash<_length, T, n - 1>(str).Value : 0)) {}
};
template<size_t _length>
constexpr __forceinline unsigned long long ComputeHash(const char(&str)[_length]) {
return CostructHash<_length, char, _length - 1>(str).Value;
}

正如你所看到的,我使用递归遍历字符串中的所有字符,但我一定在某个地方搞砸了,因为正如我所说,编译器在调用ComputeHash时会永远冻结。

我知道我一定错过了停止递归的基本情况,但据我所知,(n > 0 ? CostructHash<_length, T, n - 1>(str).Value : 0)应该完成这项工作,因为我总是将n减少1,并检查n是否大于0。那么,为什么递归没有停止呢?

此外,可能还有一种更简单的方法来做我正在尝试的事情?

您在代码中看到问题了吗

递归是无限的,因为模板实例化没有基本情况。

但据我所知,(n > 0 ? CostructHash<_length, T, n - 1>(str).Value : 0)应该完成这项工作,因为我总是将n减1,并检查n是否大于0。那么,为什么递归没有停止呢?

在编译器决定是否采用该分支之前,模板将被实例化。您必须使用if constexpr而不是三元条件,或者您必须专门针对基本情况使用模板。

此外,可能还有一种更简单的方法来做我正在尝试的事情?

这似乎很好用:

constexpr std::size_t
ComputeHash(std::string_view str) {
std::size_t result = 0;
std::size_t i = 0;
for(auto c : str) {
result += c ^ i++;
}
return result;
}

最新更新