gpt4 book ai didi

c++ - 如何将字符串转换为常量整数?

转载 作者:行者123 更新时间:2023-11-30 00:45:58 25 4
gpt4 key购买 nike

我有代表图像名称的字符串,如“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";};

问题是,在我的 case 语句中,编译器报告 shs(Pfn::fs1x1) 不是常量表达式。确切的错误信息是:

Case value is not a constant expression:

预先计算出所有哈希值然后将它们硬编码到 case 语句中真的很乏味。您对我如何在运行时以某种方式创建常量表达式有什么建议吗?

编辑:我的 shs 函数:

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);
};
};
}

最佳答案

shs 的参数需要是 constexpr 并且 shs 本身也必须是 constexpr。由于 C++11 对 constexpr 函数的限制,您可能希望为哈希的编译时版本和运行时版本提供不同的实现。

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;
}

demo

但是,请为 child 着想!除非您可以保证不会发生哈希冲突,否则这是在玩火,不适合作为生产代码。

关于c++ - 如何将字符串转换为常量整数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40713061/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com