Hello and welcome to C++ Weekly.
I'm your host, Jason Turner.
I'm available for code reviews, contracting,
and on-site training.
In a recent episode I showed you C++ 20's bind_front,
and I promised that I would come back to this and give at least
a way that it could be implemented in C++ 20.
Now I'm not going to show you actually
how the standard library will implement it,
and that is because the standard library is defined in terms
of a tuple holding the arguments, so make tuple here,
and it is defined in terms of calling standard invoke here.
We're just going to do this in pure C++ 20,
using some of the things that we've talked about lately with
lambdas and without any standard library help.
So I need to define a function called bind_front,
and I'm going to get rid of our standard library calls here.
I'm going to define it here, and well
it needs to operate just like this bind_front thing
so let's see what we can do.
[TYPING]
So I'm creating a variadic template
that takes some sort of callable function
and a set of parameters.
Now I need to return to this thing that has however
many parameters were passed to me bound to the function call.
So I'm going to use this parameter pack expansion
in lambda captures from C++ 20 to implement this.
So obviously I need to capture the actual callable thing,
but I just realized I really can't
do this completely without the standard library's help
without writing some boilerplate for move and forward.
So let's go ahead and pull those in with utility.
Now, if you recall from the episode on parameter pack
expansion and captures, I need to do it like this,
and this lets me capture all of the parameters efficiently
with a forward and now the body of the lambda.
I am returning a new lambda that I have created.
What needs to happen in here?
I need to-- well I need to give it its own parameter set,
so let's do that, and this is going
to be the additional parameters not the bound parameters.
So let's call these "bound param",
and now I need to take in another set of parameters
and this also needs to be a variadic expression.
So what in here?
I need to return the call of the function
with all of the bound parameters first,
and then all of the passed in parameters,
and I think that should pretty much do it and it does.
Now this isn't quite right.
It's mostly right.
The bound parameters, we need to take copies of those.
If we don't, we would have a slew of potential lifetime
issues, but this p, this one right here,
let's go and give this a better name.
We need to forward this along, and unfortunately forwarding
this is not quite as straightforward
as just using standard forward, because standard forward
needs to know the template parameter type here.
And, well, auto is not a template.
I mean, it is a template, but it's
a template that was written for us by the compiler.
So what do we do with this?
We need to actually get the [? decode ?]
type of the parameter pass to the template,
and then everything works as expected.
Now, to be fair, I'm quite certain
that many of you watching this are not
going to consider this really to be readable code,
but if you needed to implement something
like this you may be able to at least admit that it is quite
succinct and with perfect forwarding does give us
the performance that we would want.
Now there is still one tiny little missing detail here,
and that is the perfect returning, if you will,
of the types from the function call.
So I believe to get everything exactly how we want it,
we need to explicitly tell the compiler that we want
to [? decode ?] type auto the return
type of this function with the trailing return type
syntax for our lambda.
And this all does kind of I think work
exactly how we want it to.
Now if you think I'm wrong on this [? decode ?] type auto
bit, then go ahead and leave a comment
and we'll see if we can address that in a future episode,
but I'm pretty sure that's necessary to make
sure we get the exact type of the call
to this bound function to be maintained
through the entire call stack when we down here call
func right here.
So thank you for watching this episode of C++ Weekly.
I hope you enjoyed it.
Be sure to subscribe.