Let's assume that I want to create my own lambda-based switch with the following syntax:
auto s = make_switch(std::pair{0, []{ return 0; }},
std::pair{1, []{ return 50; }},
std::pair{2, []{ return 100; }});
assert( s(0) == 0 );
assert( s(1) == 50 );
assert( s(2) == 100 );
I would like to use a fold expression in order to have a terse implementation that does not require recursion. The idea is to generate something similar to a bunch of nested if
statements:
if(x == 0) return 0;
if(x == 1) return 50;
if(x == 2) return 100;
I would like to write this:
// pseudocode
template <typename... Pairs>
auto make_switch(Pairs... ps)
{
return [=](int x)
{
( if(ps.first == x) return ps.second(), ... );
};
}
The code above doesn't work as if(...){...}
is not an expression. I then tried to use the &&
operator:
template <typename... Pairs>
auto make_switch(Pairs... ps)
{
return [=](int x)
{
return ((ps.first == x && ps.second()), ...);
};
}
This does compile, but returns the result of ps.first == x && ps.second()
, which is a bool
and not the int
value that I want.
I would like some kind of operator that is a combination between the comma operator and &&
: it should evaluate and evaluate to the right hand side of the operator iff the left hand side evaluates to true
.
I cannot think of any technique that would allow me to implement this in such a way I can get ps.second()
's return value and propagate it to the caller of the lambda returned by make_switch
.
Is it possible to implement this kind of "cascading if
s" pattern with a fold expression? I would like to evaluate only as many expressions as required until a matching branch is found.