I am trying to get to work a switch on a string in C++, with the help of a hash. It became personal between me and this code, so I don't wanna give up and use an enum, even though I finally have only like 8 strings to put in switch cases.
Combining what I saw on other topics, I wrote this very simple and not so reliable function, but that is enough for what I want to do, as it's not professional.
My function :
constexpr long hashstr (const string &str, int h=0)
{
return !str[h] ? 55 : ( hashstr(str, h+1) *33) + (unsigned char)str[h];
}
I then call it in this very simple main function (for now), but it won't compile, telling me that the case is wrong (not a constant). I don't understand this issue, as for me the string taken in arg is a constant, plus the function returns a constant expression.
My main :
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;
}
Hoping that some of you can tell me what I'm not doing right...
Unless you are using c++20 std::string is not constexpr so can't be used in hashstr.
The value returned is larger than is representable in long, as signed arithmetic overflow is undefined behaviour your code can't be used in constexpr.
Fixing these two issues gives the working code:
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]);
}
Note that if you look at the compiler output it probably tells you why your expression isn't constexpr, e.g. clang prints:
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") :
Changing to std::string_view prints:
error: case value is not a constant expression
case hashstr("rosathefloridaturtle") :
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:9:47: note: value 97009635813568987014 is outside the range of representable values of type 'long'
return !str[h] ? 55 : ( hashstr(str, h+1) *33) + (unsigned char)str[h];
^
<source>:9:29: note: in call to 'hashstr("rosathefloridaturtle", 8)'
return !str[h] ? 55 : ( hashstr(str, h+1) *33) + (unsigned char)str[h];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With