Reputation:
What is the reason behind the fact thet switch statements in C++ have to be written with constants?
Let's take a look at the following code:
switch(variable)
{
case 1:
case 2:
case 3:
case 4:
//Code 1
break;
case 5:
case 6:
case 7:
case 8:
//Code 2
break;
default:
//Code 3
break;
}
In other languages, for example PAWN (C-Like scripting language), I could write this code down as such:
switch(variable)
{
case 1 .. 4:
//Code 1
break;
case 5 .. 8:
//Code 2
break;
default:
//Code 3
break;
}
What is the reason behind the fact the C++ switch statement is soo.. from the Stone Age? (Not to mention we can't use variables.)
Even after so many changes and updates over all those years...
Upvotes: 3
Views: 230
Reputation: 145359
The switch
was designed for a simple table-lookup, as was the Pascal case
. The Pascal case
supported ranges, with, as I recall, the same notation as for Pascal bitsets. C could have done likewise, but for whatever reasons, didn't.
And there's just not been sufficient demand for that feature to make it into either standard, C or C++.
Regarding variables or non-integral types for the case labels, that would change the nature of the statement. C and C++ simply do not have a general select
statement. But in C++ you can cook it up yourself:
template< class Key >
auto select(
const Key& key,
const map<Key, function<void()>>& actions
)
-> bool
{
const auto it = actions.find( key );
if( it == actions.end() ) { return false; }
it->second(); return true;
}
And then you can write things like
auto main() -> int
{
cout << "Command? ";
const string command = readline();
select( command, map<string, function<void()>>
{
{ "blah", []{ cout << "You said blah!\n"; } },
{ "asd", []{ cout << "You said asd!?!\n"; } }
} );
}
You can easily add a default to that if you want, e.g. by using the or
keyword.
Hm, funny I didn't think of that before, but then apparently neither did anyone else. :)
Upvotes: 1
Reputation: 70472
If you don't mind another lookup, you could generate a table to simplify your case statement:
char the_case (unsigned variable) {
static const char all_cases[] = {
0,
'A', 'A', 'A', 'A',
'B', 'B', 'B', 'B',
};
if (variable < sizeof(all_cases)) return all_cases[variable];
return 0;
}
//...
switch (the_case(variable)) {
case 'A':
//...
break;
case 'B':
//...
break;
default:
//...
break;
}
Alternatively, you can create an unordered_map
to function pointers or methods, where the key is your variable
type.
Upvotes: 1
Reputation: 16290
There's no technical reason that C switch statements couldn't be updated to use ranges. gcc already has an extension for this.
http://www.n4express.com/blog/?p=1225
There are good reasons for the values to be constant; that allows for all sorts of optimizations such as jump tables.
Upvotes: 5