如何在 C++ 中编译时枚举常量数组?
我正在尝试从字面字符串(字符数组)中编译时间生成哈希。例如:
unsigned long long compiledHash = ComputeHash("literal string");
我目前被困在寻找一种列举字符串中所有字符并创建唯一哈希的方法。如果我像平常一样使用循环的,则编译器不会在编译时生成哈希,这不是我想要的。
我可能会找到一种方法,但是在计算哈希时,编译器被卡在无限的循环中。
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&gt; 0?costructhash&lt; _length,t,n -1&gt;(str).value:0)应该做这项工作,因为我总是以1的方式减少
n
并检查n
是否大于0
。那么为什么递归不停止呢?
另外,可能还有一种更简单的方法来做我正在尝试的事情?
I am trying to generate a hash at COMPILE TIME from a literal string (array of characters). For example:
unsigned long long compiledHash = ComputeHash("literal string");
I am currently stuck on finding a way to enumerate all characters in the string and creating a unique hash. If I use a for
loop like I would normally, the compiler won't generate the hash at compile time, which is not what I want.
I might of found a way to do so, but the compiler is stuck in an infinite loop when calculating the hash.
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;
}
As you can see I use recursion to go through all characters in the string, but I must of messed up somewhere, because as I said the compiler freezes forever when it calls ComputeHash
.
I understand that I must be missing the base case that stops the recursion, but as far as I understand (n > 0 ? CostructHash<_length, T, n - 1>(str).Value : 0)
should do the job since I am always decreasing n
by 1 and checking if n
is bigger than 0
. So why is the recursion not stopping?
Also, there may be an easier way to do what I am trying?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
递归是无限的,因为没有模板实例化的基本情况。
在编译器确定是否将其采用该分支之前,对模板进行了实例化。如果constexpr 而不是三元条件,则必须使用
,或者必须专门为基本情况的模板。
这似乎很好:
The recursion is infinite because there is no base case for the template instantiations.
The template is instantiated before the compiler decides whether that branch will be taken. You have to use
if constexpr
instead of the ternary conditional, or you have to specialise the template for the base case.This seems to work fine: