Hello, and welcome to C++ Weekly. I'm your host, Jason Turner.
In this episode I'm going to discuss something that not a lot of people do.
And that is inheriting from lambdas.
Now, if you've seen my other videos on lambdas, or just in general if you know how they're implemented,
you might appreciate that they are standard types, and therefore we can do what some might consider to be surprising things.
So let's just create a simple lambda -
... and this one just returns the value four. There's really nothing surprising about this.
Now, what if we wanted to combine two lambdas,
with, maybe, two different signatures.
So if we have one that takes zero parameters it returns 4.
If we have one that takes, say, an int, it return i times 10.
This it not a really very exciting example, but I'm trying to get to a point.
Now if we wanted to combine these so that we could just call one thing,
we want to call our magical combined lambda,
and we want to call it with a 4,
or we want to call it with no parameters.
What are we going to do to make this possible?
So, one way to do this, is to take advantage of the fact that lambdas are standard types.
And we could do something like this where we are creating struct called S,
And we want to dispatch to the appropriate operator(),
depending on whatever happens to be passed to us.
But what does this actually look like? Now how do we actually construct something of type S,
and we have this problem that we don't know the type of a lambda that's unknowable information.
So we could make something like a ...
So we wanted to use perfect forwarding in our example here,
and we run into a bit of a problem,
because the type of L1 and L2 can be an r -value reference, or some other type,
so we actually have to take this one step step further.
And as you can see, this can be a bit of a pain to get right.
But what we end up with is something kind of like this.
Where we can call this function 'combined',
with the value 4, and we're going to get 4 times 10 which is 40
Or we can call it with no parameters and we're going to simply get the value 4
or if we tell it with 10, then we get 10 times 10, is a 100
So what we've done is we've managed to merge two lambdas together by taking advantage of the fact that we can inherit from lambdas.
And all of this is a bit messy. But we can take advantage of C++17's automatic class type deduction,
so that we don't actually have to use our 'make_combined' helper here.
I'm hoping.
So if we instead do auto combined, and we're just going to call S directly,
then everything continues to work as it was previously
because of this handy new feature in C++17.
Which I'm still thinking is going to enable a lot of new constructs in C++ that we have not thought about before.
Be sure to subscribe! Follow me on Twitter, and check out any of the links below.