The C++ Switch statement doesn’t actually work on strings, for example the following code would generate a compiler error (VC++ C2450):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | std::string s = "bleh"; switch( s ) { case "dude": (...); break; case "hello": (...); break; case: "bleh": (...); break; } |
Well I say, that’s a bit of a sticky wicket. So why not just resort to an if/then/else stream? Because I wanted to use the switch statement damnit! As always it was the STL to the rescue with the always lovely map class. Unlike vectors and arrays maps let you define how to access different index locations, for example you could use floats rather than integers or even strings (which is what I wanted).
To make it work with strings here’s what I did:
[sourcecode language='cpp']//quick’n'dirty hack to make C++ switch function work more
//like C#’s The following instance of the map class (switcheroo)
//holds the enum ‘Vals’ and uses strings to identify index locations
enum Vals{val1,val2,val3,val4};
static map
switcheroo[ "string1" ] = val1;
switcheroo[ "string2" ]= val2;
switcheroo[ "string3" ] = val3;
switcheroo[ "string4" ] = val4;
[/sourcecode]
Now to actually use it we simply substitute switcheroo into the switch statement and use the enum values as the cases
[sourcecode language='cpp']switch ( switcheroo[ "string3" ] )
{
case val1:
(…);
break;
case val2:
(…);
break;
case val3:
(…);
break;
case val4:
(…);
break;
}[/sourcecode]
This is obviously a little more hands on than the C# version. Perhaps a class which takes in a string and returns a unique integer value would work better, still, I’ll leave that for another day.
Yes I do realize this trick has been used by many people before me. In hindsight I should have Googled the idea of using the map class to get around the int-only limitation in C++, would have saved me a lot of time.
December 23rd, 2008 at 4:06 am
What about this code?
string s= “stringN”;
switch ( switcheroo[s] )
The expression “switcheroo[s]” will create the pair (“stringN”, Vals()). And since the type Vals is pretty much an integer, Vals() is 0. So is val1.
In other words,
string s= “stringN”;
switch ( switcheroo[s] )
{
case val1: cout << s << ” == string1″; break;
}
will proudly display:
stringN == string1
December 23rd, 2008 at 4:17 am
Hi Fabien,
I’d say the situation you’re showing off exists in many different aspects of C++. I don’t think the C++ spec’s require any variable be assigned a default value when declared, so saying int a; would give a an undefined value, I could extend that to the switch case and say,
int a;
switch ( a )
{
case 0:
(…)
}
The above would not necessarily find case 0 as ‘a’ being uninitialized could be anything. I think in VC++ the debug mode does assign a as ‘0′ but in release mode it doesn’t.
So on one hand we have a switch case which may result in an unwanted value by being assigned one by default and in the other we may still have that same unwanted value but it would be ‘undefined’.
As always it’s up to the programmer to ensure all values are assigned and working fine.
December 23rd, 2008 at 4:27 am
> Perhaps a class which takes in a string and returns a unique integer value would work better,
I’ve thought about that too. But that’d be very tricky to pull off, since the “case” statement needs an integer that’s known at compile time.