在编译时计算“const char *”字符串哈希

Jer*_*hma 5 c++ constexpr consteval

我有一个计算字符串文字的哈希值的函数:

inline consteval uint64_t HashLiteral(const char* key)
{
   // body not important here...
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

在另一个函数中,我需要文字字符串及其哈希值,我想在编译时计算它:

void function(const char* s)
{
   worker(s, HashLiteral(s));
}
Run Code Online (Sandbox Code Playgroud)

然而,似乎不可能进行这样的调用function("string"),并在编译时在其主体中计算哈希值。我现在想到的最好方法是使用宏,并重新定义函数:

#define MakeHashParms(s)   s,HashLiteral(s)
void function(const char* s, const uint64_t hash)
{
   worker(s, hash);
}
function(MakeHashParms("string"));
Run Code Online (Sandbox Code Playgroud)

是否可以有更直接的解决方案?

Bri*_*ian 3

您可以修改function以接受“散列字符串”结构,该结构可以从const char*. 如果您进行转换构造函数consteval,则可以保证哈希始终在编译时计算。

#include <cstdint>

inline consteval std::uint64_t HashLiteral(const char*)
{
   // body not important here...
   return 0;
}

struct HashedString {
    const char* str;
    std::uint64_t hash;

    consteval HashedString(const char* s)
        : str{s}, hash{HashLiteral(s)} {}
};

void worker(const char*, std::uint64_t) {};

void function(HashedString s)
{
    worker(s.str, s.hash);
}

int main() 
{
    function("string");  // OK: hash computed at compile time

    const char* x = "runtime string";
    // function(x);      // error: x is not constant expression
}
Run Code Online (Sandbox Code Playgroud)

在 godbolt 上在线尝试