Hash collisions would be one obvious problem with this approach. You could likely always tweak the hash used in response to collisions on the set of constants, but that's not going to be fun the first time it happens.
Also with that approach since it can't be made into a jump table it's still going to compile into a bunch of if/else combinations. At least with the trie it can early-return if the input doesn't have any chance of matching anything.
This is what I have done. However, you still have the risk of collisions. Depending on the context, like i did a small test and permuted all letters a-z and numbers and there are no collisions. However, changing a-z to A-Z resulted in many(may need to check code). However, this allows for a 5 character command switch.
The string compare has a lot of branching and looks at both strings. The hash method one checks the hash of the test string(size_t) with the size_t of the other string. The hash itself, say fnv1a, can be very quick(a xor and a multiply I think per character) I think I remember testing this and it was quicker. ill try to find the test, but it is easily done. Either way, it's the only way to use a switch statement this way
Something we’ve used before is preprocessor string hashing similar to . Basically we hash strings at compile time to ints and use those for our case statements. Word of caution though, there’s the possibility of collisions. It works great on a limited set of strings like XML tags and such.
Another approach not mentioned: LLVM's StringSwitch . Unfortunately it's not designed to be used independent of LLVM, so it has a dependency or two. Also note that it's a slightly different use case (can only return different values, is not used for flow control).
Although I understand people want to do some crazy stuff with template metaprogramming, I’m more concerned with how it will affect build times (you’re basically running a tree-walk interpreter in a compiler that was not supposed to run a turing complete language... it’s going to be very slow.)
For more practical reasons, what about just using runtime interned strings? Each unique string is hashed and allocated in heap memory only once, and to compare the strings you just compare the hashed values (which is just uint_64 comparison). Then you can easily use switch statements to compare your strings... As for performance, interning has an initial runtime cost for each string, but it will probably be miniscule compared to the massive compile time cost induced by crazy constexpr stuff.
Interesting. The way I would have thought of doing something like this is by laying out each "switch" case sequentially in memory, then having the "SWITCH(string)" macro expand out to something that compute the offset necessary, using a similar pre-computed trie, and jump to that offset. That way fallthrough should work as expected.