Hello, everyone.
Welcome back.
In this video, I'm going to talk about Stateful Lambdas and I'm going to show you some examples in
the ID.
I'm in the Section 21 workspace, as you can see right here, and I'm in the Stateful Lambdas Project.
So I've got ten different test functions that I'm going to show you.
Each one does something just a little bit differently, and the idea is to give you a flavor for what
stateful lambdas can do and different ways that they can do things.
So let's go over this first test example.
I've already gone ahead and built this and run it and all test cases over here running.
So I'm just going to walk you right through them, including either stream vector and algorithm, which
we'll use later.
And let me just scroll up just a little bit here.
All right.
So notice right here that we have a variable called Global X and I've initialized it to 1000.
That variable is global to this file, so it's accessible anywhere in this file.
However, I can't capture that kind of variable.
We can't capture those kinds of variables.
We can't count global variables.
For example, we can't capture static variables.
So if you try to capture that variable in the capture list right here, I'll talk about that in a minute.
The compiler is going to give you a warning about only automatic variables can be captured.
And that's all about the reaching scope of the lambda.
What can the lambda see?
So let me clear this and let's go over this one step at a time.
So remember that we've got that Global X out there and it's 1000.
Now, inside this test function, I have a local variable called X, right?
It's called local X and it's set to 100.
Now I've got my lambda expression, which I'm assigning to this variable L and notice it's got a CAPTCHA,
right?
Those square brackets, that's where we put all our captures.
So this makes this guy a state full lambda, not a state less lambda.
In this case, we're capturing local X.
That's that guy right there.
Now, by default, we are capturing by value.
That's the default capture mode.
What that means is that this lambda is going to have a copy of local X in it.
So this is called this guy local X and it is going to be a copy.
Of what it captured.
So it's going to have 100 it.
Let me write that really large.
So there's no confusion.
This is a copy in this case.
I'm making a copy of that integer.
If this variable here were to be an object, then we're going to call a copy constructor to make a copy.
So it's really important to understand that we're making a copy.
Then we're just outputting the local access value in the global access value.
So now when we call that lambda, what's going to happen is this code right here will execute the local
x will display this local x, that's the copy and it's going to display 100.
And you can see right up here my test one, it's going to display 100 and then we're going to display
Global X and it's just finding that just because of normal scope rules, it's going to find global X,
it's 1000 and it's going to display 1000 right here.
Pretty straightforward.
Now, if we try to modify local X inside the Lambda body, we're not going to be able to.
So in order to do that, we need to use the mutable keyword, and I'm going to do that in the next example.
So let me scroll up just a little bit and I'm going to scroll here to test two.
I want to scroll up here as well.
So right now we're talking about test two, which is that output right over here.
Okay.
So let's take a look at test two.
Test two, we have a local variable X and here is our lambda.
We're capturing that local variable X.
So that means that this lambda has an X.
And it's a copy of this X, so I'm going to put 100 in here.
Okay.
That's really important.
Now, when we execute the body, we're notice we're changing that x, we're incrementing it by 100.
It is allowed now because I'm using mutable, because I have that mutable keyword.
It's allowing me to do that.
So what's going to happen here is I'm going to increment the local value, not this guy, the local,
the copy.
I'm going to increment it by 100.
So this guy now becomes 200 and I'm going to display that.
So when I call the lambda, this body executes it, just incremented that to 200 and we're going to
display X, which is 200 right there.
Now when I leave, remember I just called that lamp to here and now I'm back and I'm going to display
X.
Well, the only x that this statement has access to is this X, and that X has not been changed because
we copied it.
Remember, this was a copy here.
That was a copy.
So in this case, it hasn't changed.
So what's going to display is 100.
Now, this is the piece that's really important to understand.
And a lot of students and a lot of people in general don't understand how this works with lambdas.
But it's really important to understand.
Notice what happens here.
I'm calling Lambda again.
I'm calling that lambda elegant.
So I'm going to call this lambda again.
What happens is the body of the lambda executes.
We do not capture again.
The capture only happened here when we initialize that variable.
L So we do not capture the 100.
Again, that lambda expression already has that local x and it's right here and it's 200.
All right.
So again, we're right here.
I'm calling this lambda.
It's going to increment this guy now to 300 and it's going to display 300 right there.
Now, when I come back here, I display X, which is this X that's local to this test to function,
and it's going to display 100.
Hopefully that makes sense if it doesn't make sense.
Go back to the slides and look at the slides.
And it's really important that you understand what's happening.
Remember, that's the state for Lambda.
When we have that lambda, remember that class that got created?
Remember we talked about that close your class that was created.
It has a constructor and it has.
The function call operator.
This would be the constructor.
Right here.
The constructor will be called.
Right here.
The operator function will be called right here.
The operator.
The function call operator will be called.
That's really important to understand.
The only time that we capture is when that constructor is executed.
And that's only going to be executed once.
Remember, we can only initialize an object once.
And that's exactly what LL is.
It's an object.
So, again, take your time with that.
Wrap your head around it, because it's really, really important to understand what's happening there.
Okay, so let's take a look at test three.
Now, what's happening with Test three is we're capturing by reference.
So again, I've got my X right here.
It's 100.
Now we're capturing that X by reference and that's the syntax right there.
Using that ampersand, the referencing operator.
So what happens now is and it's mutable as well.
What we're going to do now is that X is local and it's not really an X, right.
We have a reference that's really important to understand as well.
So whenever we change X, we're actually changing the actual X right here.
So what do we do here?
The body increments X by 100 and we display X, so let's call it what's going to happen.
It's going to be it's already captured x, right?
Its value is a reference to the actual we're going to increment it by 100.
What we're going to do is we're going to increment not any local copy.
There is none.
We're going to increment this guy by 100 and we're going to display it.
So that's going to display 200 here and you can see it right up there.
Now when we return from the function call, we're going to display this X right here.
It has been changed because we caught we captured by reference.
So that's also going to display 200 OC.
So that's three examples that are a little bit different from one another, but hopefully you'll see
what's going on.
All right.
So now in this case, we're going to use default capture.
By value and we're going to do it mutable just to make it more fun so we can actually change something
and you can really see what's happening.
So here we're in test four and we've got these three local variables to this test for function X, Y
and Z 102 hundred and 300.
Here's our lambda variable and we are capturing everything by value.
So that's the default capture by value.
So we're capturing X, Y and Z by value.
What's going to happen here is I'm going to make a copy of X, I'm going to make a copy of Y and I'm
going to make a copy of Z.
So X is 100, so I'm going to make that copy.
Y is 200 and Z is 300.
But now notice something.
We're not using Z in this code at all.
So the compiler is not going to capture it.
Why capture something that you're not going to use?
So this won't happen.
It's not going to waste its time doing that.
So the only thing that's captured is X and Y and you're going to get a warning in the output when you
build this program saying the variable Z was not captured since it's not being used some kind of unused
variable warning.
So again, by value, right?
So again, we've made copies.
Now I'm going to increment X by 100.
So X is now 200.
Remember this X here, not the sex here because we're capturing by value y is incremented by 100.
So I'm sorry, it's 200 here.
No, that's correct.
Y was 200.
Now Y is 300.
That's correct.
And now I'm going to output X and Y.
Right now let's call the lambda.
This will execute.
It gives us this.
And what we're going to display is right here, 203 hundred these values.
When I come back from the function call, I'm going to display X and Y, I'm not going to display this
X and this Y, not the ones in the lambda.
So that's going to display the 100 and the 200.
Okay.
So let's do a couple more and then I'll switch over to another video because this one is probably going
to get a little bit wrong in this case.
We are doing default capture by reference.
That means we're capturing everything by reference.
Those are my three variables here X, Y and Z.
I'm capturing everything by reference.
So it's a single ampersand sign in the capture list.
So what does that mean?
That means that I've got an X, Y and Z that are references to the actuals, right?
So that's what we've got.
We're not making copies of these guys.
We've got references.
And we're going to increment each by 100.
And we're going to display them.
So when I call this function, what's going to happen is this guy will become 200.
This guy will become 300.
And Z will become 400.
This function will display them.
And we're in test five.
So you can see right here we're displaying 203 hundred and 400.
Now, when we come back from the function.
We're going to display these guys while those are the same ones we just displayed.
Right, because we actually change the actuals through these references.
So, again, that should be pretty straightforward, I think.
Hopefully everything is starting to come together a little bit.
Once you get past the syntax, I think it's pretty straightforward.
Let's do one more.
And in this case, it's six.
Let me scroll up here again a little bit.
So we're in test six where we're right up here.
And in test six, we've got those three variables again, X, Y and Z.
And now what we're doing, we're capturing by value and we're capturing by reference.
So that's the syntax here.
It says Capture everything by value except y, capture y by reference.
So again, capture everything by value, but capture Y by reference and it's mutable.
So we can change those, the values we're capturing.
So now we've got our X here, we're capturing X by value.
So I'm going to copy the 100.
We're capturing y by reference.
So here's my why it's a reference.
And my z I'm capturing by value.
So my Z is going to be 300 right here, which I've copied.
And then what I'm doing is I'm just going to add 100 to each one of them.
So I'm going to call this LAMDA.
What's going to happen is I'm going to increment X by 100.
That's this guy.
I'm going to increment Y by 100.
That's my reference.
So this guy now becomes 300.
And then I'm going to increment ZE by 100, so this becomes 400.
Then I'm going to display X, Y and Z.
Well, that's 200, 300, 400.
And that's what we see right there.
When we come back from the function call, I'm willing to display X, Y and Z.
Now we're going to display these guys right up here, X, Y and Z.
So it's going to display 103 hundred and 300.
And that's what you get right there.
So I'm going to stop the video here.
And then in the next video, I'll start from Test seven and we'll start right from there.
I'll see you in the next video.