Hello and welcome to C++ Weekly.
I'm your host, Jason Turner.
I'm available for code reviews, contracting,
and on-site training.
And this episode, I am going to discuss yet another feature
of lambdas in C++.
Now as I've stated before, if you understand everything about
lambdas, you understand virtually everything there is
to know about C++ or at least all of the things that matter
in our day to day programs, I would say.
Now in this episode, I'm going to demonstrate something
that may seem a little odd at first,
but I will explain as we go along.
I'm going to create a variotic template function.
And I don't have a good name for what these template parameters
are so far, but this is a start of a variotic template
function.
Now I've got, say, something that's callable.
Let's go ahead and add it callable here,
and let's give this a smarter name now.
So I want to return a new lambda that
has bound to these parameters to this callable thing
but hasn't actually called it yet.
And we can do that.
We can create the lambda.
And we can give it no parameters.
We need actually the callable here.
Now this isn't going to compile because, as it says here,
callable is not captured, and the parameters are not
captured.
So I can do this.
I can do this equals, and I'm saying
capture all of these things by value, make copies of them.
And I can demonstrate how this function might work
so that this makes some sense.
So at this moment, in between at lines 18 and 20,
we have this lazy function here.
It's called bound.
And it's not actually going to execute the summation until we
call the function like this because this is the lambda that
was returned to us.
So we have given it to the function
that we want to bind and a couple of values
that we want to bind to.
Now this is a far stretch from being an implementation
of standard bind or something like that,
but it does give us some of the basis for something
like might work.
So if we were to only give it one parameter,
then we're going to get a compile time
error because too few parameters were passed
to the function, that is.
So this works.
It returns 3, as we expect, but we
might be concerned about a couple of things.
And that for integers this doesn't matter.
But if this was some other type, we
are taking these all by value, and then we are copying them
into the lambda.
So we're potentially making two copies of each parameter
just to bind it.
That's definitely not something that we would prefer to do.
So we think, well, perhaps what we should do here
for following the rules that say that if you know that you want
a copy of a thing to take it by value
and then move it into place, we're
left to the question of how to move it.
And we can do our this.
And we're taking the callable, and we're moving it
into our local culture.
This is a generalized capture expression--
this was added in C++ 14--
but we don't have the prams.
And so how do we capture these parameters?
We might want to do something like this.
But then we have an unexplained parameter pack,
and so we might try to expand it like this.
But then we're going to get some other error.
This isn't valid syntax here, and we just
don't know what to do here to try to efficiently get
these things in.
So what we added in C++--
no, not we.
What they have added in C++ 20 is the ability to do this
parameter pack expansion inside a generalized lambda capture.
So we can do that, and the syntax looks a little weird,
I have to fully admit.
So we're doing this dot, dot, dot here.
We're expanding the parameters, and this
does what we expect it to do.
And I still feel like personally reading this code.
I'm like, is this really doing what I think that it's doing?
So I can do this.
I can actually rename this set of parameters,
and we can see that this is now no longer compiling.
And I can do this and this is done the exact same thing.
It's just not aliasing the name here or shadowing the name
or however you want to call it.
Neither of these things would ever actually give you
a warning because you're creating
these names in a completely new scope of the lambda.
So this is the feature from C++ 20 that I want to mention.
It is specifically this-- the ability
to do parameter pack expansions inside of lambda captures.
And this is again just one of these little holes that is
helping to make C++ 20 better and in many ways,
making the language more consistent.
We can do the same things more consistently and more contexts
with C++ 20.
I feel like that is the main thing that this update
to the language for C++ 20 is really giving us.
So like I said, probably won't come up in your day
to day code, but I found it interesting, nonetheless.
And I hope you enjoyed this episode of C++ Weekly.