如何在编译时计算const char*字符串哈希?求更简洁实现方案
问题描述
我有一个用于计算字符串字面量哈希的函数:
inline consteval uint64_t HashLiteral(const char* key) { // 函数体此处省略... return 0; }
我需要在另一个函数中同时使用字面量字符串及其在编译时计算出的哈希值:
void function(const char* s) { worker(s, HashLiteral(s)); }
但调用function("string")时,无法让哈希在函数体内完成编译时计算。目前我想到的最优方案是使用宏并重定义函数:
#define MakeHashParms(s) s,HashLiteral(s) void function(const char* s, const uint64_t hash) { worker(s, hash); } function(MakeHashParms("string"));
是否存在更直接的解决方案?
更直接的解决方案
不需要依赖宏,有几种更符合C++风格的方式实现编译时哈希传递:
1. 使用模板参数传递字符串字面量(C++20及以上)
利用C++20支持的非类型模板参数字符串字面量,直接在模板层面完成哈希计算:
template <std::size_t N> void function(const char (&s)[N]) { constexpr uint64_t hash = HashLiteral(s); worker(s, hash); } // 调用时直接传字面量 function("string");
这里编译器会把字符串字面量绑定到数组引用参数,由于s是编译期已知的数组,HashLiteral(s)可以被consteval函数在编译期计算。
2. 封装成编译期结构体(C++17及以上)
定义一个包含字符串指针和编译期哈希的结构体,用constexpr构造函数初始化:
struct StringWithHash { const char* str; uint64_t hash; constexpr StringWithHash(const char* s) : str(s), hash(HashLiteral(s)) {} }; void function(StringWithHash sws) { worker(sws.str, sws.hash); } // 调用时 function({"string"});
构造StringWithHash对象时,哈希会在编译期计算完成,函数function直接使用预计算好的值。
3. 重载函数配合字面量推导
保留原单参数函数的同时,新增一个接受编译期哈希的重载,通过辅助函数推导:
// 实际工作函数 void function(const char* s, uint64_t hash) { worker(s, hash); } // 字面量专用重载,编译期计算哈希 template <std::size_t N> void function(const char (&s)[N]) { function(s, HashLiteral(s)); } // 调用方式不变 function("string");
这种方式对调用者完全透明,传字面量时会自动匹配模板重载,编译期计算哈希;如果传普通const char*,可以单独处理(比如运行时计算哈希,或者报错)。
这些方案都避免了宏的使用,更符合C++的类型安全和编译期编程范式,同时保证哈希在编译期完成计算。
内容的提问来源于stack exchange,提问作者ScratchingTheSurface
相关产品推荐
相关产品推荐

