1 00:00:05,360 --> 00:00:05,810 Okay. 2 00:00:05,810 --> 00:00:06,490 Welcome back. 3 00:00:06,500 --> 00:00:11,360 So let's continue with the examples of stateful lambdas in this case. 4 00:00:11,360 --> 00:00:17,030 I mean, Test seven and you can see that I've scrolled that up right up here so you can see my test 5 00:00:17,030 --> 00:00:18,230 seven right here. 6 00:00:18,560 --> 00:00:22,610 This basically is equivalent to the last test six that we just did. 7 00:00:22,640 --> 00:00:27,350 The difference is that rather than captured by value in one by reference, I'm capturing by reference 8 00:00:27,350 --> 00:00:28,350 and two by value. 9 00:00:28,370 --> 00:00:29,840 So it's just mixing things up. 10 00:00:29,840 --> 00:00:31,550 So let's go through this here. 11 00:00:31,550 --> 00:00:37,900 I'm saying capture everything by reference except X and Z, capture them by value. 12 00:00:37,910 --> 00:00:43,370 So again, you can see it's exactly the same thing just done a little bit different syntactically. 13 00:00:43,370 --> 00:00:46,330 We're going to capture everything by reference except X and z. 14 00:00:46,340 --> 00:00:47,300 So X. 15 00:00:48,270 --> 00:00:50,590 And Z will be copied. 16 00:00:50,610 --> 00:00:52,230 They're going to be captured by value. 17 00:00:52,260 --> 00:00:54,180 That's 103 hundred. 18 00:00:56,750 --> 00:01:00,640 And everything else, which in this case is why will be captured by reference. 19 00:01:00,650 --> 00:01:02,210 So there's my reference. 20 00:01:02,750 --> 00:01:06,950 And again, we're going to increment everything by 100 and display everything just like we did before. 21 00:01:06,950 --> 00:01:08,170 We should get the same output. 22 00:01:08,180 --> 00:01:12,350 So I'm going to call my lambda x will be incremented by 100. 23 00:01:12,350 --> 00:01:14,300 That's my local x right here. 24 00:01:14,990 --> 00:01:17,740 Y will be incremented by 100 through this reference. 25 00:01:17,750 --> 00:01:19,030 That's going to be 300. 26 00:01:20,110 --> 00:01:22,020 Z will be incremented by 100. 27 00:01:22,030 --> 00:01:23,830 So that'll be 400 right here. 28 00:01:24,740 --> 00:01:31,400 And we're going to display X, Y and Z, which are 200, 304 hundred and just what we see. 29 00:01:32,230 --> 00:01:37,900 Now, when I come back from the function, I'm going to display X, Y and Z again, we're going to display 30 00:01:37,900 --> 00:01:38,950 these guys. 31 00:01:39,250 --> 00:01:41,690 So that would be 100 and 303 hundred. 32 00:01:41,800 --> 00:01:43,510 103 hundred and 300. 33 00:01:44,840 --> 00:01:45,320 Okay. 34 00:01:45,320 --> 00:01:45,830 Perfect. 35 00:01:45,830 --> 00:01:50,330 So now let's do a few with some objects in test eight. 36 00:01:50,930 --> 00:01:56,030 I've defined a person class that's really, really similar to the person class that I defined in the 37 00:01:56,030 --> 00:01:58,400 previous stateless Lambda Demo. 38 00:01:58,400 --> 00:01:59,930 So you can see what's happening here. 39 00:01:59,930 --> 00:02:06,020 I've got my class person, I've overloaded the insertion operator to be a friend just to allow us to 40 00:02:06,020 --> 00:02:08,060 display person objects real easily. 41 00:02:08,509 --> 00:02:10,400 A person has a name and an age. 42 00:02:10,639 --> 00:02:14,210 I've got a default constructor and you can use this syntax. 43 00:02:14,210 --> 00:02:19,010 I didn't really talk about this much in the class, but it's just a handy way of telling the compiler, 44 00:02:19,010 --> 00:02:22,310 hey compiler, generate a default constructor for me. 45 00:02:22,460 --> 00:02:27,350 Sometimes it's real handy because you can actually be very explicit to tell whoever is reading your 46 00:02:27,350 --> 00:02:31,820 code, whatever other programmers reading your code, that this is exactly what you intended. 47 00:02:32,060 --> 00:02:37,280 So I've got an overloaded constructor here, a copy constructor here, and I've done the same thing, 48 00:02:37,370 --> 00:02:41,540 a destructor here, and then I've got my jets and my sets and so forth. 49 00:02:42,080 --> 00:02:46,100 Now you can see I've added three methods here, and let me just expand this so you can see what they're 50 00:02:46,100 --> 00:02:46,640 doing. 51 00:02:46,670 --> 00:02:47,270 There we go. 52 00:02:47,270 --> 00:02:53,630 So in this case, I have a method called change person one and another one called change person two 53 00:02:53,630 --> 00:02:54,590 in another one called change. 54 00:02:54,590 --> 00:02:58,580 Person three they pretty much do exactly the same thing. 55 00:02:58,580 --> 00:03:03,980 Notice that they return auto because we're returning a lambda and I just want the compiler to figure 56 00:03:03,980 --> 00:03:05,270 out the syntax for me. 57 00:03:05,270 --> 00:03:07,160 So in this case, what are we capturing? 58 00:03:07,160 --> 00:03:13,280 We're capturing this which is the this pointer we're capturing by value or capturing by reference. 59 00:03:13,280 --> 00:03:17,210 If you remember from the slides, these three things are equivalent. 60 00:03:17,330 --> 00:03:19,580 They all captured by reference. 61 00:03:19,580 --> 00:03:22,910 What I would like you to do is always use this version. 62 00:03:23,180 --> 00:03:27,920 The version with the equal sign is deprecated in C++ 20. 63 00:03:27,920 --> 00:03:30,740 That means it's not going to be supported going forward. 64 00:03:31,010 --> 00:03:36,620 That's a good thing because when a programmer sees that they're thinking captured by value and that 65 00:03:36,620 --> 00:03:39,470 doesn't happen here, what's happening is captured by reference. 66 00:03:39,470 --> 00:03:42,290 So it can be confusing and it always has been confusing. 67 00:03:42,290 --> 00:03:46,610 And this one, you know, why do it when we really want to capture the this pointer. 68 00:03:46,610 --> 00:03:50,210 So I would encourage you to use that version only. 69 00:03:50,330 --> 00:03:52,160 So look what this does. 70 00:03:52,490 --> 00:03:59,300 I have I'm capturing this and the parameters being passed into this are the new name and the new age. 71 00:03:59,300 --> 00:04:04,430 And all I'm doing is I'm setting name and age to new name and New Age respectively. 72 00:04:04,430 --> 00:04:07,970 Notice that right here I don't have to say this name. 73 00:04:09,230 --> 00:04:12,050 Right or this age right here. 74 00:04:12,590 --> 00:04:16,130 The compiler will figure that out for us because of the syntax. 75 00:04:16,470 --> 00:04:18,800 What other name could we be talking about? 76 00:04:18,800 --> 00:04:22,130 It has to be these guys, so the compiler figures that out. 77 00:04:22,130 --> 00:04:28,790 So what we're going to do is when we call these methods, the lambda will capture the this pointer and 78 00:04:28,790 --> 00:04:30,170 modify those values. 79 00:04:30,170 --> 00:04:31,160 Not a big deal. 80 00:04:31,190 --> 00:04:34,460 Pretty straightforward, but I just wanted to show you how you could capture this. 81 00:04:34,460 --> 00:04:37,610 And later on, we're going to do another example where we capture it another way. 82 00:04:37,610 --> 00:04:39,830 So let's take a look at the test here. 83 00:04:40,190 --> 00:04:41,420 And I'm only going to go over this one. 84 00:04:41,420 --> 00:04:43,100 You can see all three of them. 85 00:04:43,250 --> 00:04:44,810 There's three different examples here. 86 00:04:44,810 --> 00:04:46,940 All three will give you the exact same output. 87 00:04:46,940 --> 00:04:48,440 But in this case, look what we've got. 88 00:04:48,440 --> 00:04:50,960 We've got person Larry 18. 89 00:04:50,960 --> 00:04:53,060 So Larry is a person who's 18 years old. 90 00:04:53,060 --> 00:04:54,620 So now this is what we're going to do. 91 00:04:54,620 --> 00:04:58,910 We're going to capture using this, which is that one in person one. 92 00:04:58,910 --> 00:05:04,970 So notice what I'm doing is I'm calling change person one in person a method call just like before. 93 00:05:04,970 --> 00:05:05,390 Right. 94 00:05:05,390 --> 00:05:08,240 But this guy is returning a lambda. 95 00:05:09,290 --> 00:05:10,190 That's pretty cool. 96 00:05:10,190 --> 00:05:15,440 So now that I've got my lambda right here, I can call, I can say change person one and pass in Moe 97 00:05:15,440 --> 00:05:16,190 and 30. 98 00:05:16,700 --> 00:05:20,750 Moe is going to be passed in four for the name and 30 for the age and they're going to change. 99 00:05:20,750 --> 00:05:25,490 So when I display you're going to see something else display, right? 100 00:05:25,490 --> 00:05:29,180 You're going to see instead of Larry, you're going to see Moe display. 101 00:05:29,210 --> 00:05:30,260 Let me show you right here. 102 00:05:30,260 --> 00:05:30,650 All right. 103 00:05:30,650 --> 00:05:33,260 So remember, this is our first output statement right here. 104 00:05:33,260 --> 00:05:38,630 It just displays Larry, it looks like that now we're calling change person one and then displaying 105 00:05:38,630 --> 00:05:39,500 that value. 106 00:05:39,740 --> 00:05:41,750 And in this case, we're displaying Moe. 107 00:05:41,990 --> 00:05:44,600 And you can see here where I'm capturing by. 108 00:05:45,500 --> 00:05:51,320 Value and by reference is changing to Curly and to Frank, because I'm passing in Curly and Frank. 109 00:05:51,470 --> 00:05:56,060 So you can see that's a good example that shows how all three of these captures are equivalent. 110 00:05:56,060 --> 00:06:00,740 But as I said, no stick to using the this capture. 111 00:06:00,740 --> 00:06:02,330 That's what you're going to see out there. 112 00:06:03,020 --> 00:06:04,910 I don't think you would ever see this out there. 113 00:06:04,910 --> 00:06:08,780 I've never seen it out there, even though it's perfectly legal to use. 114 00:06:08,780 --> 00:06:10,190 And I've seen this a few times. 115 00:06:10,190 --> 00:06:14,420 But if you're capturing instance variables from an object, use this. 116 00:06:14,420 --> 00:06:16,580 It's really, really clear what your intention is. 117 00:06:17,130 --> 00:06:19,530 Okay, so that would be our test eight. 118 00:06:19,730 --> 00:06:21,560 And let's take a look at this one here. 119 00:06:21,560 --> 00:06:22,220 This is similar. 120 00:06:22,220 --> 00:06:27,020 I've got a class called Lambda and it's got a private instance variable y. 121 00:06:27,050 --> 00:06:30,860 You can see my constructor right here and there's my operator. 122 00:06:30,860 --> 00:06:31,940 Does that look familiar? 123 00:06:32,180 --> 00:06:33,470 It should look familiar, right. 124 00:06:33,470 --> 00:06:38,090 Because that's exactly like the closure class that gets created from a lambda expression. 125 00:06:38,090 --> 00:06:42,140 Remember that we've got our function call operator, we're passing in the X. 126 00:06:42,260 --> 00:06:45,440 This is exactly like the example that we went over in the slides. 127 00:06:45,440 --> 00:06:51,800 So let's take a look at the equivalence of a class like this versus a lambda expression. 128 00:06:51,800 --> 00:06:52,730 They're the same. 129 00:06:53,720 --> 00:06:55,490 Sometimes you'll see these instead of classes. 130 00:06:55,490 --> 00:06:59,510 You'll see this as a struct and everything public. 131 00:06:59,510 --> 00:07:00,110 But that's okay. 132 00:07:00,140 --> 00:07:01,700 It works exactly the same way. 133 00:07:02,180 --> 00:07:03,650 So let's test nine. 134 00:07:03,650 --> 00:07:05,060 Let me scroll up a little bit. 135 00:07:05,630 --> 00:07:05,960 All right. 136 00:07:05,960 --> 00:07:06,920 So here's test nine. 137 00:07:06,920 --> 00:07:08,960 I'm displaying the header there. 138 00:07:09,530 --> 00:07:16,430 I've got Y, which is 100 and I've creating an instance of Lambda one and I'm passing in Y, which is 139 00:07:16,430 --> 00:07:21,200 100 that is going to create this guy, it's going to call this constructor, it's going to initialize 140 00:07:21,200 --> 00:07:24,170 this to 100, just like we would expect. 141 00:07:24,170 --> 00:07:31,760 Now, when I call them to one, I'm passing the 200 here and it's going to add 102 hundred and display 142 00:07:31,760 --> 00:07:32,450 300. 143 00:07:32,930 --> 00:07:35,540 That's what's happening when we're using this class. 144 00:07:36,970 --> 00:07:41,860 In this case, I've got a lambda variable lambda to notice what we're doing. 145 00:07:41,860 --> 00:07:44,290 We're capturing y by value. 146 00:07:44,860 --> 00:07:50,710 It's got a parameter X and it's displaying the sum of x and Y exactly the same thing. 147 00:07:50,710 --> 00:07:55,420 When I call them the two with 200, you get exactly the same output. 148 00:07:55,630 --> 00:08:00,580 So you can see that these two examples are equivalent. 149 00:08:01,570 --> 00:08:03,790 That and that their equivalent. 150 00:08:03,940 --> 00:08:09,160 This kind of code is what's being generated from that lambda expression. 151 00:08:10,430 --> 00:08:14,690 And this is really important to understand because it really gives you a good insight into how these 152 00:08:14,690 --> 00:08:16,460 lambdas work behind the scenes. 153 00:08:17,470 --> 00:08:21,070 It's really nice to be able to use them, but it's even better to be able to understand how they work 154 00:08:21,070 --> 00:08:22,000 behind the scenes. 155 00:08:22,090 --> 00:08:22,420 All right. 156 00:08:22,420 --> 00:08:25,480 So let's do one more and that would be test ten. 157 00:08:26,530 --> 00:08:27,850 And for Test ten. 158 00:08:27,850 --> 00:08:30,580 I've got a lot going on here, so let me walk through this really slowly. 159 00:08:31,820 --> 00:08:39,860 In this example, I created a class called People and that people class has a bunch of person objects 160 00:08:39,860 --> 00:08:42,559 in it, but it's got a stupid vector of persons. 161 00:08:42,950 --> 00:08:46,280 So people consists of a bunch of person objects. 162 00:08:46,280 --> 00:08:51,080 And then I've also got this instance variable right here called Max people. 163 00:08:51,440 --> 00:08:55,400 Think of that as the maximum number of people that you will be able to display. 164 00:08:56,150 --> 00:09:02,270 So if there's 100 person objects in this vector and I try to display them, I should only be allowed 165 00:09:02,270 --> 00:09:08,480 to display ten or five or three or whatever this value is here and the constructor just sets this guy 166 00:09:08,480 --> 00:09:12,620 to ten by default or gives it whatever value the user supplies. 167 00:09:12,920 --> 00:09:17,690 I've got a copy constructor that I'm just defaulting and I think that's about it. 168 00:09:17,690 --> 00:09:20,600 I don't need a destructor because there's no pointers or anything here. 169 00:09:21,320 --> 00:09:23,210 Now I've got an add method. 170 00:09:23,300 --> 00:09:30,800 And what that ADD method does is it allows me to add a person to my vector right here and I can pass 171 00:09:30,800 --> 00:09:37,070 in the person's name and the person's age and I can use and place back, which creates a person object 172 00:09:37,070 --> 00:09:41,420 from these values and pushes it back onto the people vector. 173 00:09:41,420 --> 00:09:46,540 If you don't recall in place back, you can go back and look at the vectors lecture in the steel section. 174 00:09:46,550 --> 00:09:52,610 Now I've got another method right here called Set Max people and the user passes in a number and we're 175 00:09:52,610 --> 00:09:56,390 setting that instance variable to whatever they pass in and the getter as well. 176 00:09:57,580 --> 00:09:57,850 Okay. 177 00:09:57,850 --> 00:10:00,790 So now let's see how we can use a lambda with this. 178 00:10:01,270 --> 00:10:09,160 Okay, so now I've got a method called get people and get people returns a vector of persons. 179 00:10:09,520 --> 00:10:16,510 So basically what we're going to do is we're going to return all the person objects in that people class 180 00:10:17,140 --> 00:10:19,990 whose age is greater than max age. 181 00:10:20,020 --> 00:10:23,530 And I'm only going to return less than max people. 182 00:10:23,540 --> 00:10:25,270 I'm not going to go over that value. 183 00:10:26,260 --> 00:10:27,490 That's really important. 184 00:10:27,520 --> 00:10:34,480 Now, the interesting thing here is when the user calls, get people the user really has no idea about 185 00:10:34,480 --> 00:10:35,440 max people. 186 00:10:36,040 --> 00:10:37,690 They're just sending it an age. 187 00:10:37,720 --> 00:10:43,100 So I might have 100 people in this people vector that had that are over 50. 188 00:10:43,120 --> 00:10:46,240 I'm only going to display ten of them because of that value. 189 00:10:46,270 --> 00:10:47,590 Let's see how this works. 190 00:10:47,620 --> 00:10:53,320 First thing I'm doing is I'm creating a local stood vector of persons called result. 191 00:10:53,320 --> 00:10:56,200 It's empty right now and I've got to count. 192 00:10:57,010 --> 00:11:01,360 Now I'm going to use the standard template library algorithm copy if. 193 00:11:02,220 --> 00:11:09,650 And I'm going to copy matches to this result as long as they match the criteria that I mentioned. 194 00:11:09,660 --> 00:11:12,360 So right here I'm going to say Stuart, copy if. 195 00:11:12,630 --> 00:11:15,920 What are we copying from people.But begin? 196 00:11:15,930 --> 00:11:17,340 Where are we copying up to? 197 00:11:17,340 --> 00:11:20,220 People end so I'm using the entire people vector. 198 00:11:21,090 --> 00:11:27,270 And what I'm going to do is when I've got a match I'm going to use stood back and solder which basically 199 00:11:27,270 --> 00:11:34,920 pushes back whatever I'm getting into that result that vector that I'm building right here and obviously 200 00:11:34,920 --> 00:11:36,870 what I'm getting is person's right. 201 00:11:36,870 --> 00:11:42,030 So now it comes to Lambda, when do we actually do this copy if there's an if in there. 202 00:11:42,030 --> 00:11:43,590 So it has to match something. 203 00:11:43,590 --> 00:11:46,800 And let me expand this out so you can see all the code right here. 204 00:11:46,800 --> 00:11:48,420 So look at what we're doing here. 205 00:11:48,840 --> 00:11:51,420 First of all, we're capturing this. 206 00:11:51,810 --> 00:11:59,610 That allows me access to that guy, which is an instance variable in this class as well as the vector 207 00:11:59,610 --> 00:12:02,310 I'm capturing count by reference. 208 00:12:02,310 --> 00:12:04,920 That's this guy right here because I need to modify that. 209 00:12:06,470 --> 00:12:14,510 And I'm expecting a person reference that's constant and that's what copy if is going to give me. 210 00:12:15,220 --> 00:12:15,610 Right now. 211 00:12:15,610 --> 00:12:16,400 What's my predicate? 212 00:12:16,420 --> 00:12:23,560 Well, my predicate basically says if ps h that's the object that's being passed into me is greater 213 00:12:23,560 --> 00:12:28,570 than this max age and I'm going to pre increment count and make sure that it's less than or equal to 214 00:12:28,570 --> 00:12:29,290 max people. 215 00:12:30,630 --> 00:12:31,200 That's it. 216 00:12:31,200 --> 00:12:32,010 That's pretty cool. 217 00:12:32,010 --> 00:12:33,540 So you can see what we're using here. 218 00:12:33,540 --> 00:12:36,960 We're using that lambda to gain access to the object. 219 00:12:37,260 --> 00:12:40,980 And once we have access to the object, we can use all kinds of good stuff. 220 00:12:41,720 --> 00:12:45,650 So at this point, we need that we need that access to the object to get to max people. 221 00:12:46,250 --> 00:12:52,370 So now we're good at this point, we're going to return result and it's going to contain as many people 222 00:12:52,370 --> 00:12:55,670 that match that criteria as I'm allowed to print. 223 00:12:55,700 --> 00:13:00,920 Now, the idea here is, sure, this this function could have accepted the max number of people to print. 224 00:13:00,920 --> 00:13:06,500 But suppose there are two entities here, one that is setting that policy and this one that's using 225 00:13:06,500 --> 00:13:09,320 this and this function really shouldn't know about the other. 226 00:13:10,300 --> 00:13:10,400 All right. 227 00:13:10,430 --> 00:13:13,360 So let's run through a test here, see how all this works. 228 00:13:13,370 --> 00:13:18,440 So here we are in Test ten, and I've got people, friends, and then I'm going to add Larry, Curly, 229 00:13:18,440 --> 00:13:19,820 Moe, Frank and James. 230 00:13:20,360 --> 00:13:22,490 Now I'm going to call get people. 231 00:13:23,330 --> 00:13:29,810 Now, remember when I called this guy, the max was ten, so the most that I could display was ten. 232 00:13:29,810 --> 00:13:32,120 That was the default parameter in my constructor. 233 00:13:32,750 --> 00:13:37,880 When this function returns, I'm going to have a sorted vector of person objects. 234 00:13:37,880 --> 00:13:39,110 That's what this is. 235 00:13:39,110 --> 00:13:42,800 That contains all the people whose age is 17 or over. 236 00:13:42,890 --> 00:13:44,840 Now, this is basically everybody you can see. 237 00:13:44,840 --> 00:13:46,810 Everybody here is 17 or older, right? 238 00:13:46,820 --> 00:13:51,230 So once I get that, I'm just going to loop through that result and display them all. 239 00:13:51,230 --> 00:13:53,510 You can see right here, I'm getting them all. 240 00:13:55,050 --> 00:14:00,480 Now I'm going to set the maximum number of people to three, and I'm going to call that function exactly 241 00:14:00,480 --> 00:14:01,230 the same way. 242 00:14:01,230 --> 00:14:03,390 Friends target people 17. 243 00:14:03,990 --> 00:14:06,210 I'm still going to get five matches, right? 244 00:14:06,210 --> 00:14:10,440 But I'm only going to get three back because the max is three. 245 00:14:11,330 --> 00:14:16,700 Now, when I come over here and display this, I'm going to see very Curly and Moe only. 246 00:14:16,940 --> 00:14:20,330 So now let's take a look at this last example here. 247 00:14:20,570 --> 00:14:23,090 Remember, we've still got three is the max. 248 00:14:24,420 --> 00:14:26,670 Not that it matters in this case, but in this case. 249 00:14:26,670 --> 00:14:28,260 I want to get people over 50. 250 00:14:28,290 --> 00:14:30,780 Well, the only person over 50 is James. 251 00:14:31,020 --> 00:14:33,030 So all we get back is James. 252 00:14:33,480 --> 00:14:38,820 Had there been 40 people that are over 50, I only would have gotten three of them back and displayed 253 00:14:38,820 --> 00:14:39,540 only three. 254 00:14:39,780 --> 00:14:41,370 This can be really handy sometimes. 255 00:14:41,370 --> 00:14:43,800 You've got a game going on and you've got players. 256 00:14:43,800 --> 00:14:48,750 You've got a whole bunch of players, but only a certain number of players meet a certain criteria and 257 00:14:48,750 --> 00:14:52,620 there may be so many of them that you just want to randomly pick one, two or three or give you the 258 00:14:52,620 --> 00:14:57,570 first three back or the first ten back, depending on what logic is running in the program. 259 00:14:57,920 --> 00:14:59,670 Okay, so that's it. 260 00:14:59,670 --> 00:15:02,970 Those are a bunch of examples for State Full Lambdas. 261 00:15:02,970 --> 00:15:04,530 Hopefully the stuff makes sense. 262 00:15:04,530 --> 00:15:09,180 There's a lot of other examples that obviously you can play around with and create yourself. 263 00:15:09,420 --> 00:15:16,260 In the next video we'll wrap up this section and we'll go over some examples of using lambdas with the 264 00:15:16,260 --> 00:15:22,770 standard template library algorithms, some simple use cases, and we'll just kind of pick a bunch of 265 00:15:22,770 --> 00:15:25,770 example algorithms and try them out and show you how that works.