Click here to Skip to main content
15,881,715 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
My turn to ask a question.

It was just pointed out to me that the switch statement is completely unnecessary in the C++ language. There is no reason at all to use it anymore.

Being a dinosaur I still use it. And find it useful in CAD/CAM/CNC programming that have years of experience in.

Let's take a common example in the CAD world. The DXF File.

In this format, every primitive type is denoted by a number.

Say, you encounter the following numbers to instantiate from.
100
201
300
305

Now you need to instantiate different object type types from these. It could be Strings, memo text, fonts, lines, polylines, circles, etc... You get the idea I'm sure... Don't worry about getting the exact number matched with a data type. The numbers don't necessarily follow a logical pattern. Many skips in the sequences are evident.

Could some provide a concise code example of how to instantiate different kinds of objects from these numbers without using switch statements, function mapping, or if else trees'?

Thank you.

Bonus:
In the DSTV format, object types are denoted by string literals. A similar solution for these would be interesting to see.
Posted
Comments
Romain TAILLANDIER 16-Dec-11 3:30am    
I am a quite new programmer (near 10 years of C#) comparing to you Jack 'Dinosaur' Dingler :)
I agree, switch is not necessary. as the else is. (if(a){...}if(!a){...}
There this many form of loop, for, while, doWhile, (and now foreach in C#), only one should be necessary
There is the linq language ..., not necessary
There is a swarm of unnecessary keywords, function concepts ...
But it is just a easy way to do, read and maintain the things.

Being a dinosaur, wouldn't you exclusivly use assembler ? or perfored card ? :)

I am aout of the question, it's happend ... but may i suggest you to take a look to brainfuck ? I am sure you would like it ! Nothing unnecessary !

Finally back to your question, I try to reply in C# with your permition (not good enough in C++).
I would have created a hashtable containning numbers (100, 201, 300, 305...) as keys, and type names ("Namespace.Circle", "System.String" ...) as string values.
Then getting the number i would retrieve the type name using this table and use the reflection.emit to instanciate the type. (not so far from Emilio Garavaglia solution)

well ... there are alternatives to "big switches" but the fact they are convenient depends case by case.

Think to different "actions" ("create this" / "create that") as different functions, and think to a table having the numbers you mention as key and function pointer as values

with an
std::map<unsigned, creatable* (createfn*)()> yourmap;
initialized appropriately, you can just create your objects (suppsed to derive from shape) as
creatable* newobject= yourmap[id]();


Similarly, every time you have to differentiate an action based on an ID you can use similar dispatch tables or -where a common interface exist- virtual functions.

In C++11 you can even declare
std::map<unsigned, std::function<creatable*> >
having the capability -at that point- to use whatever functor type (classes implementing the () operator, or even lambda expressions) returning a creatable*...

Note that you can replace what I used to be unsigned (referring to numbers) with std::string to use textual identifiers
 
Share this answer
 
v5
Comments
JackDingler 15-Dec-11 9:29am    
Right. but these are just function arrays and function maps. I use those a lot.

We had those in 'C', they aren't something new that C++ gave us.

And logically, these are runtime versions of the switch statement.

The message mapping in MFC, simply scans the list comparing the values until it finds a match. The switch statement does the same thing.

Your example of
std::map<unsigned, creatable*="" (createfn*)()=""> yourmap;
is simply an optimization of the same technique. And if you look at old versions of various interpreters written in K&R 'C', you'll find the same techniques used.
Emilio Garavaglia 15-Dec-11 10:14am    
It the Touring equivalence is valid, everything you can invent is... syntactic sugar for an if/goto that is what -as an ultimate analysis- what the CPU finally does.

Big switches are replaced by virtual functions, and where virtual function cannot apply (like in object construction) with map dispatching. And map dispatching can be implemented in various ways, via std::map or via template specialization or "static fabric objects". But everything, given your state point, will always noting more than the "distribution of the switch".

The point is how the switch is maintainable and extendible either from the inside (by changing it) or the outside (adding elements in a time other than the "switch" development)
JackDingler 15-Dec-11 10:43am    
Exactly.

This is where I take issue with claims made in print, back when C++ was emerging, that the C++ was going eliminate the concept of the switch entirely. I think it's mistaken meme that has caught on, and colored the community's thinking.

Perhaps for many programmers coming out of school today, much of the underlying framework seems to be mostly magic?
Emilio Garavaglia 15-Dec-11 12:59pm    
"Perhaps for many programmers coming out of school today,..." Good question, it depends on the school.

By my personal experience, programmers comes from two types of school: engineering and computing science.
The first start study the computer as a system (a finite state automata) then abstract systems over systems. Touring equivalence is a consequence, and languages equivalence is for them clear from the beginning (they typically start programming controllers machine code). Mastering a language is understanding a proficient way to build product and tools with it. Paradigm (like OOP) and patterns (like composite-visitors) are just "formalization of good common sense" (I understand certain pattern are known with certain names after years of usage of them my own).
The seconds start studying "computing" (not computers) as a formal way to express algorithms. Pattens and paradigms are tough as formalisms, Touring equivalence is tough as a mathematical theorem, and the existence of physical machines that mimics a given language is... postulated.
Until they don't see the correspondence with the physical word, a certain level of ... magic is perceived. For engineers, the "magic" is, instead, their capability in hiding the "tricks".
nv3 15-Dec-11 11:03am    
Is the switch statement completely unnecessary in C++? No.

Can the same be achieved with other language constructs? Yes.

Can it be achieved with the same syntactic elegance? No.

Can it be achieved with the same run-time efficiency? Depends on how smart the compiler is. In a switch statement its obvious that the same expression is going to be compared to many tags. With if ... else if constructs that is not the case. And if a mapper class is as efficient as the compiler switch code is not guaranteed.

Hence I would say, not every syntactic construct that can be replaced by other things is unnecessary. Language syntax has also to do with ease of use and tun-time efficiency. My 2 cents...
Here's a stab at switch-less solution.

Create some sort of coordinator class that allows multiple different object factory classes to register themselves inside of the coordinator. Each different object factory class knows how to create one particular kind of object, all presumably based on some common abstract base class of object (e.g., a "generic" CAD object), and knows how to accept or reject an invitation to create an object based on a parameter that defines the code number for a primitive.

To create an object, feed the coordinator a stream of code numbers for the primitives (e.g., 100, 201, 305, etc). For each one, the coordinator goes through its list of registered factories, and asks each in turn if it wants to be the one to create the object. The coordinator continues through its list until the object is created, or every registered factory has declined the invitation to create the object.

Note that the architecture is easily upgraded, to add new types of factories for new types of primitives, without a need to touch the code for the coordinator class or the code for any of the other existing factories.

Mike
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900