【发布时间】:2013-04-07 11:05:24
【问题描述】:
我已经编写了一些代码,通过使用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 Hash function 的constexpr 递归。因此它为 const char* 创建了一个完整的散列,希望它是唯一的散列。
我对此方法有一些疑问:
- 这是一种安全的使用方法吗?或者这种方法在特定用途中可能是一种邪恶?
- 您能否编写一个更好的散列函数,为每个字符串创建不同的整数,而不受字符数的限制? (按我的方法,长度够长了)
- 您能否编写一个代码,通过
conststr将const char*隐式转换为int constexpr,这样我们就不需要美观的丑陋(以及时间消耗)_const用户定义的字符串文字?例如OUT<"String">将是合法的(并将“字符串”转换为整数)。
任何帮助将不胜感激,非常感谢。
【问题讨论】:
-
如果我的回答“解决”了您的问题,是否可以将其标记为已接受?否则,您可以(再次)评论它!
-
哦,对不起,我总是忘记这样做:)
标签: c++ templates c++11 string-literals constexpr