Creating my own flow control statements in C++. Is that acceptable? I always considered 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 &lt;functional&gt;
#include &lt;tuple&gt;

template&lt;typename V&gt;
bool switch_on(const V&amp; value)
{
    return false;
}

template&lt;typename V, typename P, typename... Args&gt;
bool switch_on(const V&amp; value, const P&amp; p, Args... args)
{
    if(std::get&lt;0&gt;(p)(value, std::get&lt;1&gt;(p)))
    {
        std::get&lt;2&gt;(p)();
        return true;
    }
    else
    {
        return switch_on(value, args...);
    }
}

template&lt;template &lt;typename&gt; class P, typename F, typename V &gt;
auto case_of(const V&amp; v, const F&amp; p) -&gt; decltype( std::make_tuple(P&lt;V&gt;(), v, p) )
{
    return std::make_tuple(P&lt;V&gt;(), v, p);
}

template&lt;typename P, typename F, typename V &gt;
auto case_of(const V&amp; v, const F&amp; p) -&gt; decltype( std::make_tuple(P(), v, p) )
{
    return std::make_tuple(P(), v, p);
}

template&lt;typename F, typename V &gt;
auto case_of(const V&amp; v, const F&amp; p) -&gt; decltype( std::make_tuple(std::equal_to&lt;V&gt;(), v, p) )
{
    return std::make_tuple(std::equal_to&lt;V&gt;(), v, p);
}


so I can use:

using std::less;
using std::greater;

int main()
{
    int a = 42;
    switch_on(a,
        case_of&lt;less&gt;(0, [&amp;]{
            std::cout &lt;&lt; "LESS THAN ZEROOOOOOOOOOOOOO."; 
        }),
        case_of(42, [&amp;]{
            std::cout &lt;&lt; "Yes";
        }),
        case_of&lt;greater&gt;(9000, [&amp;]{
            std::cout &lt;&lt; "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.
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:


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?