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

发布于 2025-01-20 17:34:39 字数 1130 浏览 0 评论 0原文

我正在尝试从字面字符串(字符数组)中编译时间生成哈希。例如:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

她如夕阳 2025-01-27 17:34:39

您在代码中看到了问题

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

,但据我了解(n&gt; 0?costructhash&lt; _length,t,n -1&gt;(str).value:0)应该做这项工作,因为我总是在减少n到1并检查n是否大于0。那么为什么递归不停止?

在编译器确定是否将其采用该分支之前,对模板进行了实例化。如果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;
}

Do you see the problem in the code

The recursion is infinite because there is no base case for the template instantiations.

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?

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.

Also, there may be an easier way to do what I am trying?

This seems to work fine:

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文