Why the switch statement cannot be applied on strings?
The reason why has to do with the type system. C/C++ doesn't really support strings as a type. It does support the idea of a constant char array but it doesn't really fully understand the notion of a string.
In order to generate the code for a switch statement the compiler must understand what it means for two values to be equal. For items like ints and enums, this is a trivial bit comparison. But how should the compiler compare 2 string values? Case sensitive, insensitive, culture aware, etc ... Without a full awareness of a string this cannot be accurately answered.
Additionally, C/C++ switch statements are typically generated as branch tables. It's not nearly as easy to generate a branch table for a string style switch.
As mentioned previously, compilers like to build lookup tables that optimize switch
statements to near O(1) timing whenever possible. Combine this with the fact that the C++ Language doesn't have a string type - std::string
is part of the Standard Library which is not part of the Language per se.
I will offer an alternative that you might want to consider, I've used it in the past to good effect. Instead of switching over the string itself, switch over the result of a hash function that uses the string as input. Your code will be almost as clear as switching over the string if you are using a predetermined set of strings:
enum string_code {
eFred,
eBarney,
eWilma,
eBetty,
...
};
string_code hashit (std::string const& inString) {
if (inString == "Fred") return eFred;
if (inString == "Barney") return eBarney;
...
}
void foo() {
switch (hashit(stringValue)) {
case eFred:
...
case eBarney:
...
}
}
There are a bunch of obvious optimizations that pretty much follow what the C compiler would do with a switch statement... funny how that happens.
C++
constexpr hash function:
constexpr unsigned int hash(const char *s, int off = 0) {
return !s[off] ? 5381 : (hash(s, off+1)*33) ^ s[off];
}
switch( hash(str) ){
case hash("one") : // do something
case hash("two") : // do something
}