I have a function that calculates the hash of a string literal:
inline consteval uint64_t HashLiteral(const char* key)
{
// body not important here...
return 0;
}
In another function I need both the literal string, and its hash which I want to have calculated at compile-time:
void function(const char* s)
{
worker(s, HashLiteral(s));
}
It seems however be impossible to make such a call like function("string")
and have the hash calculated in its body at compile-time. The best I came up for now is using a macro, and redefine the function:
#define MakeHashParms(s) s,HashLiteral(s)
void function(const char* s, const uint64_t hash)
{
worker(s, hash);
}
function(MakeHashParms("string"));
Is a more straightforward solution possible?
You could modify function
to accept a "hashed string" structure which can be implicitly constructed from a const char*
. If you make the conversion constructor consteval
, you can guarantee that the hash is always computed at compile time.
#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
}