Switch Statements

This topic is 4248 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

I have learned how to use switch statements with characters for input, but is there a way to do it with numbers or strings?

Share on other sites
With integers, yes. With floats, no. With strings, no.

Share on other sites
You can do it with any numeric integral type. You can also do it with strings in C# and PHP, in C or C++ you would have to resort to a sequence of else if.

Darn, my computer won't post this message! Damn you to hell, computer!

EDIT: integral! I swear I meant integral.

Share on other sites
The way I did it with strings was a series of an if and else ifs. like so:

			if(!strcmp(buffer, "most likely option"))			{ ... } //Do thing for first			else if(!strcmp(buffer, "second most likely option"))			{ ... }			else if(!strcmp(buffer, "third most likely option"))			{ ... }

Thats how I did it. I would also order the test strings in the order of how likely it will be selected, it should help imrove the speed somewhat.

Share on other sites
And there isn't even the intention to fix this in C++0x...

Share on other sites
There isnt any need for this to be "fixed". Switch statements are usually used only in the case of the simplest comparisons. For a complex comparison like a floating point number or a string, etc, it just makes more sense to use the if and else statements.

I, for one, have never really had the need or desire to use strings in a switch (except perhaps about 6 or 7 years ago when I learned what a switch was).

Share on other sites
Quote:
 Original post by medevilenemyThere isnt any need for this to be "fixed". Switch statements are usually used only in the case of the simplest comparisons. For a complex comparison like a floating point number or a string, etc, it just makes more sense to use the if and else statements.I, for one, have never really had the need or desire to use strings in a switch (except perhaps about 6 or 7 years ago when I learned what a switch was).

Sorry, but no...

(except floats, of course)

Share on other sites
Quote:
Original post by TrueTom
Quote:
 Original post by medevilenemyThere isnt any need for this to be "fixed". Switch statements are usually used only in the case of the simplest comparisons. For a complex comparison like a floating point number or a string, etc, it just makes more sense to use the if and else statements.I, for one, have never really had the need or desire to use strings in a switch (except perhaps about 6 or 7 years ago when I learned what a switch was).

Sorry, but no...

(except floats, of course)

Perfect post there, chum. Care to elaborate with us "inferiors"?

Share on other sites
Do lookups in a map instead:

std::string s;// populate s here// function style// oldif (s == "foo") { foo(); }else if (s == "bar") { bar(); }// lots more cases hereelse { do_default(); }// new// Note you need more sophisticated stuff in order to deal with member functionstypedef void(*func)();typedef std::map<std::string, func> funcmap;funcmap funcs;funcs["foo"] = foo;funcs["bar"] = bar;// lots more cases herefuncmap::iterator it = funcs.find(s);if (it == funcs.end()) { do_default(); }else { it->second(); }// For simple assignments to variables:// oldstd::string s;// populate s hereif (s == "foo") { x = 0; }else if (s == "bar") { x = 1; }// lots more cases hereelse { x = -1; }// newtypedef void(*func)();typedef std::map<std::string, int> funcmap;funcmap funcs;funcs["foo"] = 0;funcs["bar"] = 1;// lots more cases herefuncmap::iterator it = funcs.find(s);if (it == funcs.end()) { x = -1; }else { x = it->second; }

Share on other sites
Why wouldn't you want switch to work with more types? C#'s switch works on strings, it surely comes in handy sometimes. O'Caml/SML/Haskell use switch-like statements for pattern matching. Lisp has cond, the most general switch possible, which works with predicates (but then again can't be optimised by the compiler). And why shouldn't it also work on floating point values? Just make it smart enough so that it knows it has to work with epsilons for comparisons.

Of course, it depends on where to draw the line between what is a switch and what isn't.

Share on other sites
Quote:
 Original post by SamLowryWhy wouldn't you want switch to work with more types? C#'s switch works on strings, it surely comes in handy sometimes. O'Caml/SML/Haskell use switch-like statements for pattern matching. Lisp has cond, the most general switch possible, which works with predicates (but then again can't be optimised by the compiler). And why shouldn't it also work on floating point values? Just make it smart enough so that it knows it has to work with epsilons for comparisons.Of course, it depends on where to draw the line between what is a switch and what isn't.

I consider switch to be stylistically deprecated, with the exception of performance hacks.

Now, it's awfully useful for the hacks (and I do use it for that), but: In general, the type of behavior that switch is mean to handle is "I'm running some general purpose code, and now I'm going to specialize my action based on some sub-type." That type of thing is usually more elegantly handled with polymorphism.

All that said, if C++ did support a switch on a float, it would be a huge mistake for it to work with epsilons. C++ doesn't intrinsically support an "almost equal" for floating point types, and it wouldn't make sense to start embedding that in any extensions.

Share on other sites
Quote:
 Original post by JasonBlochowiakNow, it's awfully useful for the hacks (and I do use it for that), but: In general, the type of behavior that switch is mean to handle is "I'm running some general purpose code, and now I'm going to specialize my action based on some sub-type." That type of thing is usually more elegantly handled with polymorphism.

This seems to be common sense but isn't always the best solution.

Quote:
 Steve Yegge wrote:In the meantime, I hope I've made my main point clear, which is that polymorphism only makes sense when the polymorphic behavior is really a behavior of the target. When it's the behavior of the observer, you need runtime typing.

When Polymorphism Fails

<edit> Which is going to be a bit offtopic, sorry for that, but it is still a good read</edit>

Share on other sites
Quote:
Original post by JasonBlochowiak
Quote:
 Original post by SamLowryWhy wouldn't you want switch to work with more types? C#'s switch works on strings, it surely comes in handy sometimes. O'Caml/SML/Haskell use switch-like statements for pattern matching. Lisp has cond, the most general switch possible, which works with predicates (but then again can't be optimised by the compiler). And why shouldn't it also work on floating point values? Just make it smart enough so that it knows it has to work with epsilons for comparisons.Of course, it depends on where to draw the line between what is a switch and what isn't.

I consider switch to be stylistically deprecated, with the exception of performance hacks.

Now, it's awfully useful for the hacks (and I do use it for that), but: In general, the type of behavior that switch is mean to handle is "I'm running some general purpose code, and now I'm going to specialize my action based on some sub-type." That type of thing is usually more elegantly handled with polymorphism.

So, in a way, if-statements are also hacks?

You should take a look at SmallTalk if you don't know it yet, it might become your new favorite language.

Share on other sites
Quote:
Original post by TrueTom
Quote:
 Original post by JasonBlochowiakNow, it's awfully useful for the hacks (and I do use it for that), but: In general, the type of behavior that switch is mean to handle is "I'm running some general purpose code, and now I'm going to specialize my action based on some sub-type." That type of thing is usually more elegantly handled with polymorphism.

This seems to be common sense but isn't always the best solution.

Quote:
 Steve Yegge wrote:In the meantime, I hope I've made my main point clear, which is that polymorphism only makes sense when the polymorphic behavior is really a behavior of the target. When it's the behavior of the observer, you need runtime typing.

When Polymorphism Fails

<edit> Which is going to be a bit offtopic, sorry for that, but it is still a good read</edit>

Well, clearly the most coherent point that emerges from that post is that you shouldn't blog after three glasses of wine.

His secondarily useful point is that you shouldn't spread clumps of client behavior around like they were dandylion seeds in a tornado. How exactly that hard-binds to whether or not polymorphism is an appropriate choice for a task at hand eludes me at the moment, though.

Anyways, note that I implicitly avoided Golden Hammer syndrome in my original post, by specifically providing an example of when my primary point doesn't apply, as well as using the incredibly useful escape hatch of "is usually more elegantly handled ...". :)

Share on other sites
Quote:
Original post by SamLowry
Quote:
 Original post by JasonBlochowiakI consider switch to be stylistically deprecated, with the exception of performance hacks.Now, it's awfully useful for the hacks (and I do use it for that), but: In general, the type of behavior that switch is mean to handle is "I'm running some general purpose code, and now I'm going to specialize my action based on some sub-type." That type of thing is usually more elegantly handled with polymorphism.

So, in a way, if-statements are also hacks?

You should take a look at SmallTalk if you don't know it yet, it might become your new favorite language.

No, if statements by themselves aren't hacks. Properly used, they evaluate a set of conditions - not a set of types. Types can be determined effectively at compile or object creation time, and shouldn't generally need to be queried all the time.

This:

if (s == "something") ;else if (s == "somethingelse") ;else if (s == "ohnonotmore") ;else if (s == "dearsweet(subdeityofyourchoice)makeitstop") ;else if (s == "pleeeese") ;else Throw("My lack of planning has lead you to this exception");

use of if statements is a hack. Unfortunately, it's one that actually shows up in some folks' production code - sometimes running to multiple pages.

Obviously, all this boils down to a judgement call - in real production environments with full sized teams, even with quality coders, there's more of a tendency to put new judgement-based-on-type code in new (mostly client) code, rather than pushing it down towards leaf classes when appropriate. I've seen far less instances of over-distribution of responsibility than I've seen inappropriate under-distribution; hence, my leanings are towards preventing the under-distribution.

Cheers,
Jason

p.s. Smalltalk was fun to play with, but its performance is nowhere near what's necessary for commercial game production (at least for core code). Then again, it's been almost 10 years since I last took a look...

Share on other sites
Quote:
 Original post by JasonBlochowiakAnyways, note that I implicitly avoided Golden Hammer syndrome in my original post, by specifically providing an example of when my primary point doesn't apply, as well as using the incredibly useful escape hatch of "is usually more elegantly handled ...". :)

That wasn't meant as critisicm by any means, just ranting that most people claim that using switch with the type of an object is bad and you should use polymorphism instead, but don't realize that the switch is nothing else than overloading a function (which is just a different kind of polymorphism).