patterncppMinor
Creating my own flow control statements in C++. Is that acceptable?
Viewed 0 times
flowcontrolcreatingstatementsownthatacceptable
Problem
I always considered
Because of said reasons, and also as an exercise on lambdas and variadic templates I created my own flow control function.
so I can use:
While in Lisp, it is encouraged to create new forms of flow control, what about C++? I would also like to see some opinions about template usage, some pointers on how to improve the code and possible corner cases when this code will break.
switch statement as somehow defective:- works only on integral types and enumerations.
- isn't an readability improvement over traditional if/else chain.
- forget a
break- you have a bug.
- variable declaration spills over neighbouring cases.
- is essentially a computed goto
Because of said reasons, and also as an exercise on lambdas and variadic templates I created my own flow control function.
#include
#include
template
bool switch_on(const V& value)
{
return false;
}
template
bool switch_on(const V& value, const P& p, Args... args)
{
if(std::get(p)(value, std::get(p)))
{
std::get(p)();
return true;
}
else
{
return switch_on(value, args...);
}
}
template class P, typename F, typename V >
auto case_of(const V& v, const F& p) -> decltype( std::make_tuple(P(), v, p) )
{
return std::make_tuple(P(), v, p);
}
template
auto case_of(const V& v, const F& p) -> decltype( std::make_tuple(P(), v, p) )
{
return std::make_tuple(P(), v, p);
}
template
auto case_of(const V& v, const F& p) -> decltype( std::make_tuple(std::equal_to(), v, p) )
{
return std::make_tuple(std::equal_to(), v, p);
}so I can use:
using std::less;
using std::greater;
int main()
{
int a = 42;
switch_on(a,
case_of(0, [&]{
std::cout (9000, [&]{
std::cout << "IT'S OVER NINE THOUSAAAAAAAAND!!!";
})
);
}While in Lisp, it is encouraged to create new forms of flow control, what about C++? I would also like to see some opinions about template usage, some pointers on how to improve the code and possible corner cases when this code will break.
Solution
Lisp has an uniform syntax, so it’s possible to create user defined flow control constructs that look exactly like the built in constructs. In C++, that’s generally not possible.
Your code is certainly clever, and it solves the problem of omitted breaks (I consider the other drawbacks you list less important). However:
Your code is certainly clever, and it solves the problem of omitted breaks (I consider the other drawbacks you list less important). However:
- Despite naming this a “switch”, you’ve essentially recreated an if-else chain. Notably, a compiler may have a bit more difficulty optimizing this than a traditional switch.
- Your implementation does not seem to support range comparisons or a default case, although both of these seem to be doable in your conceptual framework.
- When used in a disciplined way, falling through from one switch case to the next is not always devoid of merit.
- I’m not sure that returning this boolean has a great benefit. It might be preferable to design a construct that ensures that one of the cases is always executed.
- Be honest: do you really find this more readable than a traditional switch statement?
Context
StackExchange Code Review Q#26952, answer score: 8
Revisions (0)
No revisions yet.