The switch
in the C++ standard cannot implement string case matching, but we often have this need, so let’s implement it.
The desired result is as follows:
1 | switch("123"){ |
Directly matching strings is not possible; in C++, case
can only match a constant expression of the same type as the type of condition after conversions and integral promotions
, so here I need to convert the string to a literal integer for case matching.
To convert a string to a number, we can use HASH (Wikipedia - hash function) to compute it, and here I am using the hash algorithm from Chromium to calculate the hash value of string strings (Chromium - string_piece.h).
The hash calculation code is as follows:
1 | // Hashing --------------------------------------------------------------------- |
We need to use the HASH_STRING_PIECE
macro definition here.
With C++11 features, we can define a constexpr
function (for details, see the end-of-article links) and call this constexpr
function at the case
label of the switch.
Here, I wrote a recursive function to implement the above hash calculation:
1 | constexpr size_t HASH_STRING_PIECE(const char *string_piece,size_t hashNum=0){ |
At this point, we can write in the switch like this:
1 | switch(HASH_STRING_PIECE("123")){ |
For convenience, we can overload the ""
operator to facilitate its use instead of calling the HASH_STRING_PIECE
function directly every time, also to better conform to case usage specifications.
1 | constexpr size_t operator "" _HASH(const char *string_pice,size_t){ |
Then it can be used like this:
1 | switch(HASH_STRING_PIECE("123")){ |
If you want to directly use the standard library string, you can write a function like this:
1 | size_t CALC_STRING_HASH(const string& str){ |
Then, when directly passing a string object, you can call the CALC_STRING_HASH
function:
1 | int main(int argc,char* argv[]) |