我已经写了一些代码,使用constexpr
将const char *
转换为int
,因此我可以使用const char *
作为模板参数。这是代码:
#include <iostream>
class conststr
{
public:
template<std::size_t N>
constexpr conststr(const char(&STR)[N])
:string(STR), size(N-1)
{}
constexpr conststr(const char* STR, std::size_t N)
:string(STR), size(N)
{}
constexpr char operator[](std::size_t n)
{
return n < size ? string[n] : 0;
}
constexpr std::size_t get_size()
{
return size;
}
constexpr const char* get_string()
{
return string;
}
//This method is related with Fowler–Noll–Vo hash function
constexpr unsigned hash(int n=0, unsigned h=2166136261)
{
return n == size ? h : hash(n+1,(h * 16777619) ^ (string[n]));
}
private:
const char* string;
std::size_t size;
};
// output function that requires a compile-time constant, for testing
template<int N> struct OUT
{
OUT() { std::cout << N << '\n'; }
};
int constexpr operator "" _const(const char* str, size_t sz)
{
return conststr(str,sz).hash();
}
int main()
{
OUT<"A dummy string"_const> out;
OUT<"A very long template parameter as a const char*"_const> out2;
}
在这个示例代码中,out
的类型是OUT<1494474505>
,而out2
的类型是OUT<106227495>
。这段代码背后的魔法是conststr::hash()
,它是一个使用FNV哈希函数的constexpr
递归函数。因此,它为const char*创建了一个整数哈希值,希望这是唯一的。我有一些关于这种方法的问题:
- 这是一种安全的使用方式吗?或者在特定情况下,这种方法可能会产生一些问题吗?
- 你能否编写更好的哈希函数,使每个字符串都创建不同的整数,而不限制字符数?(在我的方法中,长度足够长)
- 你能否编写一段代码,通过
conststr
将const char*
隐式转换为int constexpr
,从而我们将不需要美观丑陋(而且也浪费时间)的_const
用户定义的字符串字面量?例如OUT<"String">
将是合法的(并将"String"转换为整数)。
非常感谢您的帮助。