我有代表图像名称的字符串,如" foobar.png"等等 如您所知,C ++中的switch-case不支持切换字符串。
我试图通过将字符串散列到std :: size_t,然后在switch-case语句中使用该值来解决此问题。
例如:
//frameName is an std::string which represents foobar.png etc..
switch (shs(frameName)) { //shs is my hash func which returns std::size_t;
case shs(Pfn::fs1x1): //Problem in this line
default:{
break;
}
}
在单独的文件(Pfn.hpp)中:
命名空间Pfn { const std :: string fs1x1 =" fs1x1&#34 ;; };
问题是,在我的case语句中,编译器报告shs(Pfn::fs1x1)
不是常量表达式。确切的错误消息是:
案例值不是常量表达式:
事先计算出所有哈希值然后将它们硬编码到case语句中真的很乏味。你有什么建议我怎么能在运行时以某种方式创建常量表达式?
编辑:我的功能:
static std::size_t shs(std::string string){
return Hash::shs::hs(string);
}
// ...
namespace Hash{
struct shs{
public:
inline std::size_t operator()(const std::string &string)const{
return hashString(string);
}
static std::size_t hs(const std::string &string){
std::size_t seed = 0;
hash_combine(seed,string);
return seed;
}
//From Boost::hash_combine.
template <class T>
static inline void hash_combine(std::size_t& seed, const T& v)
{
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
};
};
}
答案 0 :(得分:3)
shs
的论点必须是constexpr
,而shs
本身也必须是constexpr
。有可能,由于对constexpr函数的C ++ 11约束,您可能希望为编译时版本和哈希的运行时版本提供不同的实现。
我wrote前一段时间关于这个主题的帖子,使用fnv1a作为哈希算法。以下是重要部分:
常量:
typedef std::uint64_t hash_t;
constexpr hash_t prime = 0x100000001B3ull;
constexpr hash_t basis = 0xCBF29CE484222325ull;
运行时哈希:
hash_t hash(char const* str)
{
hash_t ret{basis};
while(*str){
ret ^= *str;
ret *= prime;
str++;
}
return ret;
}
编译时哈希:
constexpr hash_t hash_compile_time(char const* str, hash_t last_value = basis)
{
return *str ? hash_compile_time(str+1, (*str ^ last_value) * prime) : last_value;
}
用户定义的字符串文字:
constexpr unsigned long long operator "" _hash(char const* p, size_t)
{
return hash_compile_time(p);
}
和用法:
switch(fnv1a_64::hash(str)){
case "first"_hash:
cout << "1st one" << endl;
break;
case "second"_hash:
cout << "2nd one" << endl;
break;
case "third"_hash:
cout << "3rd one" << endl;
break;
default:
cout << "Default..." << endl;
}
但是,请想想孩子们!除非你能保证不存在哈希冲突,否则这就是玩火,不适合作为生产代码。
答案 1 :(得分:2)
我假设你的哈希不会因为这个答案而发生任何冲突。
如果您将哈希定义为预处理器函数,则可以创建可以匹配的常量。
答案 2 :(得分:1)
根据定义,常量表达式表示可以在编译时计算的表达式。
但如果case func():
为constexpr,则可以使用func()
。