我正在尝试在散列的帮助下在 C++ 中切换字符串。它在我和这段代码之间变得很私人,所以我不想放弃并使用枚举,即使我最终只有 8 个字符串可以放在 switch case 中。
结合我在其他主题上看到的,我写了这个非常简单并且不太可靠的函数,但是对于我想做的事情来说已经足够了,因为它不专业。
我的功能:
constexpr long hashstr (const string &str, int h=0)
{
return !str[h] ? 55 : ( hashstr(str, h+1) *33) + (unsigned char)str[h];
}
Run Code Online (Sandbox Code Playgroud)
然后我在这个非常简单的 main 函数中调用它(现在),但它不会编译,告诉我情况是错误的(不是一个常量)。我不明白这个问题,对于我来说 arg 中的字符串是一个常量,加上函数返回一个常量表达式。
我的主要:
int main (void) {
string teststr;
cout << "test string :::> ";
cin >> teststr;
int tt = hashstr(teststr);
cout << "res --> " << tt << endl;
switch ( hashstr(teststr) )
{
case hashstr("rosathefloridaturtle") :
cout << "ROSA OK" << endl;
break;
default:
cout << "ERROR" << endl;
break;
}
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
希望你们中的一些人可以告诉我我做错了什么......
除非您使用的是 c++20 std::string,否则constexpr不能在hashstr.
返回的值大于 中可表示的值long,因为有符号算术溢出是未定义的行为,您的代码不能在 中使用constexpr。
解决这两个问题给出了工作代码:
constexpr unsigned long hashstr (const std::string_view &str, int h=0)
{
return !str[h] ? 55 : ( hashstr(str, h+1) *33) + (unsigned char)(str[h]);
}
Run Code Online (Sandbox Code Playgroud)
请注意,如果您查看编译器输出,它可能会告诉您为什么您的表达式不是constexpr,例如 clang 打印:
constexpr unsigned long hashstr (const std::string_view &str, int h=0)
{
return !str[h] ? 55 : ( hashstr(str, h+1) *33) + (unsigned char)(str[h]);
}
Run Code Online (Sandbox Code Playgroud)
更改为std::string_view打印:
error: case value is not a constant expression
case hashstr("rosathefloridaturtle") :
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:22:18: note: non-literal type 'const std::string' (aka 'const basic_string<char>') cannot be used in a constant expression
case hashstr("rosathefloridaturtle") :
Run Code Online (Sandbox Code Playgroud)