hey what's going on folks it's Mike here and welcome to the next lesson our modern C plus plus Series in this lesson we're going to continue talking about lambdas now this lesson is going to build up a little bit of the previous lesson so you should understand at least basics of what a Lambda is but specifically I'm going to be talking about the capture that's the thing between the brackets so with that said let's go ahead and get started and review a little bit and then talk about the capture all right so again our structure for a Lambda as highlighted at line five here is we have our captures which we're going to talk about today parameters and a body here now in the previous Lambda lesson what I went ahead and did was we created a vector I created this thing called last result and then we went ahead and set up a Lambda here where I had one parameter here taking in the input the body of the function here setting the last result to n printing out the result and then we use this Lambda in an actual for each Loop here or the for each algorithm just to be specific because we're going to start doing more stuff with algorithm here and we went ahead and printed everything out so let's just go ahead and compile and run this program and again if you don't understand this please check out the previous video and the playlist on lambdas now what is going on here with this last result here because we can see what's going on is I have a local variable here called Last Resort or excuse me last result and I go ahead and set it to negative one and then we can go ahead and see that it's being modified here now what is the actual type here of Ampersand last result well it's a reference type so what I have here which I sort of sketched out in the last video basically again confirming that well what a Lambda is is a funk door essentially is some approximation of this here now I've gone ahead and added inline here because it's probably an inline function and if I'm doing the Ampersand here this is specifically capturing and setting a reference here so I should add this just to be a little bit more correct here now we're not quite done with this example I'm going to go ahead and show you exactly what is being set up here but let's go ahead and just ignore this for now and then talk about the actual capture okay so first thing that we need to know about our Lambda functions is if I'm not capturing anything what is this so let's just go ahead and get rid of here nothing in our capture I'm going to go ahead and try to compile this and we'll see that well we're going to get an error here because we're using something here that we don't have access to even though it sort of looks like it's available here okay so let's just go ahead and get rid of this so it compiles at line 13 here so I'll just delete that and now we'll go ahead and compile and we're good to go here okay so let's just talk about this this thing that captures nothing here this right here what I have at line 13 is essentially a raw function pointer okay so I'll try to get the exact syntax right here on what our function pointer is but it's gonna be something like void doesn't return anything we'd give it a name here print V something like that it's a pointer uh type here so I'll put a pointer here and then any of the parameters so it looks something like that for our actual function pointer so essentially that's all this is it's just a function in fact I could go ahead and you know move this up here again call this void print uh V function just so it has a different name here and go ahead and do standard C out with one parameter into n here print out and and then The Comma just so you can see that this is the same thing here okay it's just like a regular function call it just happens to have a scope that's only going to be you know within main where we can use this okay but of course we can pass this into standard algorithm them places that accept things that are callable which we'll have to talk about stud function raw pointers and Funk doors which we've talked about in this playlist okay so that's the basic idea capturing nothing nothing new here old C style function pointers okay but let's go ahead and say hey it's kind of interesting if when we call this function we want to capture something so let's go ahead and do that I'll get rid of this here and let's just get rid of our notes here because we're going to be changing things now as I've shown you before if we want we can capture by Reference last result here and if we want to capture by reference I can put an ampersand here and that will capture or now we can use last result here last result equals n here okay and that'll actually store the value and in fact let's actually do multiple values here so I'll do last result two and we'll just store the same thing here again for demonstration purposes so I'll make this a comma to break up the list here and we have a list of all the things that we want to capture last result too also equals n again very boring but we're just going to print these out here just to go ahead and show you how this works that we can capture both results and again it's just going to be nine and then 9 again okay so very simple uh how that's working in the sense that we're just saying Hey by reference you know I want to in this thing that's eventually going to get wrapped up as a function object or a functor store these results here for last result uh one and two here essentially now there is a shorthand that we can actually use if we want to use our compiler and just capture both these results I can just pass in Ampersand here and let's just go ahead and recompile that to show you that this works and I'll go ahead and compile this okay so piece of cake again to show you that this works here okay it's just the compiler is smart enough to say hey what are the things that are sort of outside of the scope here that we're using and let's just make sure to capture those okay so the compiler is doing a little bit more work here and capturing both of these things now this tends to be what I use because my um lambdis that I write tend to be very short they're usually predicates again doing some sort of test in a standard algorithm so I tend to use this but sometimes you do want to be very explicit with what you're actually capturing here so that some program can't come in here and just start adding variables and change how your program is running all right so as that said here again you're probably familiar with this idea here pass by reference and if you're not again check out the C plus plus playlist but what if we don't actually want uh to preserve last result here so again the last result the last thing that's getting printed out here again in our Vector one two three two five nine again as we sort of iterate through each of these elements here using for each is going to be nine so again that's why we're seeing nines here both times but let's go ahead and get rid of this Ampersand and what if I just type in last result and last result two here okay so this time without doing it by reference let's go ahead and compile and this time we actually get an error here okay so let's go ahead and show you the full uh compiler error here I'll move it to the top so you can see and it says assignment of read only variable last result okay so we're passing in this value here and we're actually not allowed to assign if we're passing by copy here okay so let me go ahead and show you that this code will compile here okay so for instance if I just want to use a value um let's go ahead and just do uh standard C out and we'll just print out last result here in our Lambda and again this isn't production code or anything but just demonstrating that this works now okay and our output is going to be really wonky right we're just printing negative 1 everywhere here in an end line but we can actually use values here so we're passing in a copy of the actual variable uh we can use it but we can't uh reassign it to anything it's just passing in read only but what if we actually do want to pass in a copy of last result that starts off as negative one and then actually change it so modify it so that it's not read only or const well as we've learned in this series or maybe you know in your C plus plus we have a keyword for that and that keyword is mutable okay so what we can actually do after our capture is type mutable here and now go ahead and recompile this um so that we can see what happens oops I got an error here well how can I remember this well mutable doesn't go after the capture it goes actually after the uh parentheses because again uh and the way that you can remember this is remember this is like a uh the pens in a function object if you watch the functor video uh but mutable after here and then now we could go ahead and compile this uh and now it'll actually work now let's actually go ahead and run this so what this is saying is um hey you can use this variable we can actually uh change it so let's actually change something in here let's put these back in here so last result uh go ahead and compile okay so it's compiling but now let's go ahead and figure out what's the result going to be so this is saying hey I can pass in a copy here it's not going to be read only so I can change it so the question is when I actually in my program here uh run this and print out the last result is this going to be changed here is it going to be modified and the answer to that when I run it is it's not I'm going to get negative 1 here okay and let me go ahead and just clean up the output here sorry let's get rid of uh line 19 just to run it again and show you again what happened so compiles runs and last result is preserved here why because again in our capture we're passing in a copy so we're allowed to now uh write over our copy by using mutable here but at the end of the day this isn't going to change anything any of our local variables here that were in scope so that's just something to keep in mind if you want to actually pass in copies and again not change the result but sometimes you do want to be able to pass by copy so again that you're not modifying things but you want to be able to mutate that copy within the Lambda so I hope that makes sense and I hope that's clear now likewise just with the pass by reference the little shortcut by just passing in an ampersand for everything that's going to be captured you can also just pass in a equal sign here and that's going to capture last result and last result to here okay so let's go ahead and let's go ahead and just compile that here again let me focus on this here save this was the change here and I'll compile run and again it works just the same here okay so about as simple as example that we can get here this time again mutable controlling weather we can read or write over this value all right now a few other things to show you here and then I'll actually jump into CPP insights just so you can go ahead and know a tool to use to see how lambdas are again being implemented now let's talk about using lambdas and other types of variables so we've only been using locals here so I want to talk about what happens when you have a global variable for instance so let's just go ahead and say global and we'll assign it to something here and my question is um and let's go ahead and just let's get rid of a few of these things here just to make it a little bit easier and I'll go ahead and let's just go ahead and you know pass in let's pass in by copy here okay and we'll make me uh let's get rid of last result actually but we'll say Hey you know everything that we need here we can modify and we'll do this a little bit let's just go ahead and change Global to 10 here and we'll just go ahead and print out Global here okay so just setting up the problem here and let me give ourselves a little bit of screen space so that you can actually see here um I mean let's sort of think about this again for my sort of system standpoint Global is well the storage is going to be everywhere right so what happens if I change a global variable here okay let's go ahead and save and go ahead and recompile this rerun and Global is in fact going to be 10 okay because the storage duration of global or Global variable is the duration of your program so it doesn't matter where I change it even our Lambda and again you know we're doing the copy thing which again before had something about read only again this is just showing that you can modify Global no matter what because again it's everywhere and this is going to be the same for if you have a static variable right so I can make this static here and do the same experiment here rerun it it's going to change it just the same here okay because static duration is you know the lifetime of your actual program so just two other things to keep in mind okay uh so I hope that makes sense I hope that's useful for you to see these different things for the Lambda capture again just as very few we looked at passing by copy and if we want to change those copies we need to use the mutable keyword so again let's go ahead and just put that in here mutable here so if I want to change uh last result for instance this will work or I can do even better and just say hey let's pass by reference don't need it the mutable keyword here because last result will get passed in by reference so again it will change here and if I compile and run it here and then if I passing any Global variable so let's just go ahead and combine everything here let's just go ahead and set our Global equal to you know nine ninety nine thousand nine hundred ninety nine um and we could go ahead and see that that's going to change because its duration is everywhere all right now we're not quite done because I want you to understand just a few more things here in this example so let me get rid of the source code here let me get rid of the global variable just to clean things up a little bit and what I want to do here is again just show you this code what the actual compiler is going to do with this type of code here so let me go ahead and quit out of this here let's go ahead and print out this program I'm just going to copy it and what I'm going to go ahead and do is copy and paste this into CPP insights which is a wonderful tool here for showing us what's actually going on in our code and I'll tell you what to pay attention to in one moment here oh let's just get rid of the global here here last result we'll print that out and I'm using C plus plus uh 20 here but you know anything should be fine here but all right here's what we've got here on our actual program and again all we're doing here is we've got this one Lambda function here uh for us and let's go ahead and just keep everything in view for us just so I can scrunch this down a little bit more uh there we are and there we are here all right um all right so again all this stuff setting up our Vector setting up the last result and then you can see when we create this Lambda here again it's creating that function object for us now it's just kind of putting this uh Lambda here within our actual main okay so it's embedding the class here and again compiler generated stuff you'll usually see with two underscores so again that's what we're getting here so let me just highlight this to focus on it and then we can actually see uh it's creating uh this actual uh so this instance of this class here which is our Lambda here because again lambdas are just function objects or Funk doors so something that is implementing the operand with the uh parens here so again just highlighting this this is what makes it a function object something with State um so that's what we've got here okay and then you can go ahead and see that the body of whatever we had in our Lambda here that is inside of the operand prime or the parentheses and we sort of get the idea here now since we're talking about captures in this lesson though the thing that I'm going to go ahead and show you is what the member variable is that's generated here we get a private variable here that's a uh reference here okay so it has to refer to something that exists somewhere else okay so here it is and we could go ahead and see when we're constructing this as part of our capture that's where we're again assigning this or initializing this actual variable here so let's go ahead and um let's come back in our example here let's add in last result two and then let's actually use last result uh number two here somewhere in our code and then pay attention carefully here uh to our Constructor that's going to change here now our code's going to change here as well and then we should also get another member variable here okay so let's go ahead and just run this give it a moment to compile and me and I went to scroll to the right spot so here we see our second member variable here and then we see our Constructor has changed appropriately to capture these items okay so that's the idea here that we can see here now again there are some little things here like this is going to be a inline function here and it's it's const but you know we're working with reference variables here so we can mutate them now let's go ahead and just see what happens if I do um pass with equals here and then what I'm going to go ahead and do here is we want to just maybe just use these variables they're not going to do anything useful but let's go ahead and see how our function is generated here okay so again um and and our compiler hasn't optimized these output so we see that we have these two variables this time here though you can see that they're not reference types but they're just regular integers okay matching the type of the two things that we're capturing within our function here we can go ahead and see that you know the construction it's just building a copy from these but again the really interesting thing here is to see that this is just const here okay so that's why we had to add mutable previously uh and let's just go ahead and add mutable here on CPP insights and let's go ahead and see that should modify these two member variables here um so that they can be mutable oops let's see here it says warning expression result unused okay we got two uh warnings here let's go ahead and just uh run it anyway I might have to actually change these for it to do anything let's go ahead and say equal seven and equals eight and if we go ahead and take a look here let's see what the compiler decided to do now could have done two things it could have made these uh variables mutable and left the cons here it looks like it just got rid of the const here so that we could actually change some stuff around here seems like that was the easiest thing to do but that's the idea now you can see we can actually modify these copies but again remember because these are you know part of this actual class they're not going to change you know the actual last result later because again they are within this Lambda scope so maybe if you Nest things or whatever that might be useful to hold on to now something that I haven't talked about which is probably a more advanced uh topic is that you can actually pass in this for instance and there's lots of other different things that you can go ahead and do with lambdas but you know I think we've got the main parts here that you'd want to talk about uh or know about when when discussing the actual capture when it comes to lambdas alright folks I hope that was a useful lesson I know it's uh maybe a lot coming out yet once but just remember equal sign Ampersand and sometimes you have to use the mutable keyword if you want to mutate things now I think C plus plus sort of got the defaults right with the pass by copy and making things const and forcing you to use that mutable I think that was actually a good uh sort of default to have and then of course if you do need to change things the Ampersand is useful though okay so that said with enough recap review and again you can go ahead and see in CPP insights how these things are actually implemented which is interesting to see go ahead and try that experiment with a little code example like this so I'll go ahead and cut this video off here I hope it was interesting I hope you enjoyed it if you have comments below please let me know and otherwise thanks for your time attention and we'll see you folks in the next lesson
Get free YouTube transcripts with timestamps, translation, and download options.
Transcript content is sourced from YouTube's auto-generated captions or AI transcription. All video content belongs to the original creators. Terms of Service · DMCA Contact