我正试图在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;
}