1 00:00:00,000 --> 00:00:02,242 (gentle music) 2 00:00:02,242 --> 00:00:05,220 (keyboard clacking) 3 00:00:05,220 --> 00:00:06,840 Frank: In this video, we'll look at what it means 4 00:00:06,840 --> 00:00:10,080 for a lambda expression to be stateless. 5 00:00:10,080 --> 00:00:12,330 You might be surprised to hear that you're already familiar 6 00:00:12,330 --> 00:00:14,550 with stateless lambda expressions. 7 00:00:14,550 --> 00:00:15,480 In the last video, 8 00:00:15,480 --> 00:00:18,270 we looked at the structure and syntax of a lambda 9 00:00:18,270 --> 00:00:21,420 and said that a lambda's capture list allows it to capture 10 00:00:21,420 --> 00:00:24,510 the context or closure in which it executes. 11 00:00:24,510 --> 00:00:26,580 But what if the capture list is empty? 12 00:00:26,580 --> 00:00:29,430 An empty capture list means that the expression captures 13 00:00:29,430 --> 00:00:31,860 no information from its environment 14 00:00:31,860 --> 00:00:34,470 and only knows about the information passed to it 15 00:00:34,470 --> 00:00:36,660 via the function parameter list. 16 00:00:36,660 --> 00:00:39,900 This is what's known as a stateless lambda expression. 17 00:00:39,900 --> 00:00:42,660 Now, let's take a look at some examples. 18 00:00:42,660 --> 00:00:46,230 In this example, we have two stateless lambda expressions. 19 00:00:46,230 --> 00:00:47,520 We can tell that they're stateless 20 00:00:47,520 --> 00:00:49,680 from their empty capture lists. 21 00:00:49,680 --> 00:00:51,660 The first expression takes no parameters 22 00:00:51,660 --> 00:00:54,480 and simply displays Hi when executed. 23 00:00:54,480 --> 00:00:56,640 Everything it needs to execute is contained 24 00:00:56,640 --> 00:00:58,530 within its function body. 25 00:00:58,530 --> 00:00:59,940 The second expression 26 00:00:59,940 --> 00:01:02,760 takes a single integer x as a parameter 27 00:01:02,760 --> 00:01:05,160 and displays a value of x when it's called. 28 00:01:05,160 --> 00:01:07,920 We can see that this lambda is instantiating a call 29 00:01:07,920 --> 00:01:11,280 with the value of 100 as its x parameter. 30 00:01:11,280 --> 00:01:13,890 But we can also see that another integer x 31 00:01:13,890 --> 00:01:15,870 has been defined above. 32 00:01:15,870 --> 00:01:19,470 Can you tell which x value lambda will display? 33 00:01:19,470 --> 00:01:22,320 Remember this lambda expression is stateless, 34 00:01:22,320 --> 00:01:25,350 and so it captures no information from its environment. 35 00:01:25,350 --> 00:01:27,540 This means that the lambda has no knowledge 36 00:01:27,540 --> 00:01:30,000 of the integer x defined above 37 00:01:30,000 --> 00:01:31,590 and only knows about the value 38 00:01:31,590 --> 00:01:33,750 that was assigned to its parameter x 39 00:01:33,750 --> 00:01:36,180 when it was instantiated and called. 40 00:01:36,180 --> 00:01:39,540 Since the parameter x was assigned a value of 100, 41 00:01:39,540 --> 00:01:42,302 the lambda will display 100. 42 00:01:42,302 --> 00:01:46,080 In this example, the lambda expression called sum 43 00:01:46,080 --> 00:01:49,500 takes an integer array and its length as parameters 44 00:01:49,500 --> 00:01:50,640 and returns the sum 45 00:01:50,640 --> 00:01:53,280 of the integers contained within the array. 46 00:01:53,280 --> 00:01:56,040 We can see that the lambda's parameter names are the same 47 00:01:56,040 --> 00:01:59,670 as the integer array and length defined above. 48 00:01:59,670 --> 00:02:02,430 But, again, we know from the empty capture list 49 00:02:02,430 --> 00:02:04,530 that this lambda expression is stateless, 50 00:02:04,530 --> 00:02:05,820 so it has no knowledge 51 00:02:05,820 --> 00:02:08,610 of the array defined above or its length. 52 00:02:08,610 --> 00:02:10,889 The only way for the lambda to compute the sum 53 00:02:10,889 --> 00:02:13,200 of the integers contained within the array 54 00:02:13,200 --> 00:02:15,630 is if the array and its length are passed 55 00:02:15,630 --> 00:02:17,760 to the lambda as parameters. 56 00:02:17,760 --> 00:02:20,610 We can see this being done when the lambda is called, 57 00:02:20,610 --> 00:02:23,793 and so the lambda will compute and return the sum 60. 58 00:02:25,057 --> 00:02:28,140 So far, we've only seen lambda expressions 59 00:02:28,140 --> 00:02:30,000 that use value parameters, 60 00:02:30,000 --> 00:02:31,027 but you're probably wondering, 61 00:02:31,027 --> 00:02:33,420 "Could they also be reference parameters?" 62 00:02:33,420 --> 00:02:34,860 Absolutely. 63 00:02:34,860 --> 00:02:36,840 Remember that by passing a parameter 64 00:02:36,840 --> 00:02:39,450 by reference to a function or lambda expression, 65 00:02:39,450 --> 00:02:42,510 you're passing the location of the actual parameter. 66 00:02:42,510 --> 00:02:45,000 So the form of parameter in the function body 67 00:02:45,000 --> 00:02:47,520 is an alias to the actual parameter. 68 00:02:47,520 --> 00:02:51,300 Unlike passing by value, no copy will be made. 69 00:02:51,300 --> 00:02:52,920 When you change the form of parameter, 70 00:02:52,920 --> 00:02:54,870 you're changing the actual parameter. 71 00:02:54,870 --> 00:02:56,907 Let's take a look at an example. 72 00:02:56,907 --> 00:03:00,390 In this example, we have the lambda expression called bonus 73 00:03:00,390 --> 00:03:03,630 that takes as its parameters two test scores 74 00:03:03,630 --> 00:03:05,790 and a number of points to increase them by. 75 00:03:05,790 --> 00:03:09,000 You'll notice that both score1 and score2 76 00:03:09,000 --> 00:03:11,040 are reference parameters, 77 00:03:11,040 --> 00:03:13,740 so any changes made to them within the lambda body 78 00:03:13,740 --> 00:03:16,590 will change the parameters they're referencing. 79 00:03:16,590 --> 00:03:18,060 This means that there's no need 80 00:03:18,060 --> 00:03:19,890 to return the increased scores 81 00:03:19,890 --> 00:03:21,690 since the parameters they're referencing 82 00:03:21,690 --> 00:03:23,760 will already have been updated. 83 00:03:23,760 --> 00:03:25,530 We can see that bonus is called 84 00:03:25,530 --> 00:03:29,700 and passed test_score1, test_score2, and 5 85 00:03:29,700 --> 00:03:30,930 as the number of bonus points 86 00:03:30,930 --> 00:03:33,180 to be awarded to each test score. 87 00:03:33,180 --> 00:03:35,340 As the lambda body executes, 88 00:03:35,340 --> 00:03:39,510 score1 and score2 are increased by five points, 89 00:03:39,510 --> 00:03:41,070 but these are just aliases 90 00:03:41,070 --> 00:03:44,970 for the parameters test_score1 and test_score2. 91 00:03:44,970 --> 00:03:47,790 So it's actually test_score1 and test_score2 92 00:03:47,790 --> 00:03:50,190 that are being increased by five points. 93 00:03:50,190 --> 00:03:52,770 Once the lambda has finished executing, 94 00:03:52,770 --> 00:03:54,600 test_score1 and test_score2 95 00:03:54,600 --> 00:03:57,660 are displayed with their updated values. 96 00:03:57,660 --> 00:04:00,330 You may remember that in C++, it's possible 97 00:04:00,330 --> 00:04:04,470 to use pointer parameters to achieve pass by reference. 98 00:04:04,470 --> 00:04:05,700 So naturally it follows 99 00:04:05,700 --> 00:04:09,600 that lambda expressions can also use pointers as parameters. 100 00:04:09,600 --> 00:04:11,820 To use pointer parameters properly, 101 00:04:11,820 --> 00:04:14,580 we need to remember that the pointer parameter is pointing 102 00:04:14,580 --> 00:04:17,490 to the address of the parameter that's being passed. 103 00:04:17,490 --> 00:04:19,110 So when calling the lambda, 104 00:04:19,110 --> 00:04:22,560 we need to use the referencing or address of operator 105 00:04:22,560 --> 00:04:25,080 to pass the address of the parameter. 106 00:04:25,080 --> 00:04:28,050 Additionally, because the lambda pointer parameter 107 00:04:28,050 --> 00:04:31,320 is pointing to the address of the actual parameter, 108 00:04:31,320 --> 00:04:33,300 if we want to access or modify 109 00:04:33,300 --> 00:04:35,250 the parameter stored at that address, 110 00:04:35,250 --> 00:04:37,950 we need to use the dereferencing operator. 111 00:04:37,950 --> 00:04:39,600 All of this was covered in detail 112 00:04:39,600 --> 00:04:41,640 in Section 12 of the course. 113 00:04:41,640 --> 00:04:43,230 But I think it's important that you know 114 00:04:43,230 --> 00:04:46,230 it can also be implemented with lambda expressions. 115 00:04:46,230 --> 00:04:48,360 Now, let's quickly take a look at that example 116 00:04:48,360 --> 00:04:49,920 with the bonus lambda expression 117 00:04:49,920 --> 00:04:52,140 but this time using pointers. 118 00:04:52,140 --> 00:04:54,630 Notice the differences from the last example. 119 00:04:54,630 --> 00:04:58,860 The parameters score1 and score2 are now pointer parameters. 120 00:04:58,860 --> 00:05:00,360 So when bonus is called, 121 00:05:00,360 --> 00:05:03,180 the referencing or address of operator is used 122 00:05:03,180 --> 00:05:07,260 to pass the addresses of test_score1 and test_score2. 123 00:05:07,260 --> 00:05:10,620 We can also see that the dereferencing operator is used 124 00:05:10,620 --> 00:05:14,520 to modify the values that score1 and score2 are pointing to 125 00:05:14,520 --> 00:05:16,320 within the lambda body. 126 00:05:16,320 --> 00:05:18,690 Now that we've seen how lambda expressions can use 127 00:05:18,690 --> 00:05:20,580 values, references, and pointers 128 00:05:20,580 --> 00:05:23,070 as parameters for different data types, 129 00:05:23,070 --> 00:05:24,757 you may be asking yourself, 130 00:05:24,757 --> 00:05:28,080 "Can the same be applied to data structures and objects?" 131 00:05:28,080 --> 00:05:29,940 And the answer is of course. 132 00:05:29,940 --> 00:05:32,400 Let's take a look at how we can use vectors 133 00:05:32,400 --> 00:05:35,640 as reference parameters to pass multiple test scores 134 00:05:35,640 --> 00:05:38,160 to the lambda expression bonus. 135 00:05:38,160 --> 00:05:40,710 Here, we see that the lambda expression bonus takes 136 00:05:40,710 --> 00:05:44,160 as its parameters a reference to an integer vector 137 00:05:44,160 --> 00:05:47,550 containing the scores to be awarded bonus points 138 00:05:47,550 --> 00:05:50,790 and an integer number of bonus points to be awarded. 139 00:05:50,790 --> 00:05:52,080 Within the lambda body, 140 00:05:52,080 --> 00:05:54,450 a range base for loop is used to iterate 141 00:05:54,450 --> 00:05:57,810 over each individual score contained within the vector. 142 00:05:57,810 --> 00:06:00,330 You'll notice that the referencing operator is used 143 00:06:00,330 --> 00:06:04,470 in front of score in the range declaration of the for loop. 144 00:06:04,470 --> 00:06:06,390 This is because we want to modify 145 00:06:06,390 --> 00:06:08,970 the scores contained within the vector. 146 00:06:08,970 --> 00:06:10,770 If we didn't use the referencing operator, 147 00:06:10,770 --> 00:06:13,410 no changes made within the body of the lambda 148 00:06:13,410 --> 00:06:15,360 would carry outside of it. 149 00:06:15,360 --> 00:06:16,950 We can see that bonus is called 150 00:06:16,950 --> 00:06:20,160 and passed the integer vector test_scores and 5 151 00:06:20,160 --> 00:06:21,360 as the number of bonus points 152 00:06:21,360 --> 00:06:23,730 to be awarded to each test score. 153 00:06:23,730 --> 00:06:26,040 Once the lambda has finished executing, 154 00:06:26,040 --> 00:06:28,500 the updated test scores are displayed. 155 00:06:28,500 --> 00:06:29,760 Pretty simple, right? 156 00:06:29,760 --> 00:06:32,040 But what if the vector test scores contain 157 00:06:32,040 --> 00:06:34,680 floating-point values instead of integers? 158 00:06:34,680 --> 00:06:37,770 Could we modify this lambda expression so that it could take 159 00:06:37,770 --> 00:06:40,470 both integer and floating-point vectors 160 00:06:40,470 --> 00:06:42,420 as its scores parameter? 161 00:06:42,420 --> 00:06:45,030 Moreover, is there a way to write any lambda expression 162 00:06:45,030 --> 00:06:48,060 to accept any data type for a single parameter? 163 00:06:48,060 --> 00:06:49,537 Let's find out. 164 00:06:49,537 --> 00:06:52,770 Here we have two variables, num1 and num2, 165 00:06:52,770 --> 00:06:55,710 which are of type integer and float, respectively. 166 00:06:55,710 --> 00:06:58,410 The lambda expression l takes a parameter x 167 00:06:58,410 --> 00:07:00,450 and displays its value. 168 00:07:00,450 --> 00:07:03,990 What type specifier would we need to use for parameter x 169 00:07:03,990 --> 00:07:05,520 so that the lambda could display 170 00:07:05,520 --> 00:07:08,750 both num1 and num2 when called? 171 00:07:08,750 --> 00:07:11,880 Just like we use the keyword auto to tell the compiler 172 00:07:11,880 --> 00:07:14,760 to deduce the type of the lambda expression, 173 00:07:14,760 --> 00:07:17,040 we can also use it to tell the compiler 174 00:07:17,040 --> 00:07:19,320 to deduce the type of the parameter. 175 00:07:19,320 --> 00:07:22,380 This is a very powerful concept in C++, 176 00:07:22,380 --> 00:07:24,810 and it's commonly used with lambda expressions 177 00:07:24,810 --> 00:07:27,990 to increase robustness, performance, and usability. 178 00:07:27,990 --> 00:07:29,970 Let's see how we can implement this concept 179 00:07:29,970 --> 00:07:31,353 with our last example. 180 00:07:32,430 --> 00:07:35,280 We can see now that by changing the type specifier 181 00:07:35,280 --> 00:07:37,860 of the scores parameter to auto, 182 00:07:37,860 --> 00:07:39,570 the lambda expression can be passed 183 00:07:39,570 --> 00:07:42,000 both integer and floating-point vectors. 184 00:07:42,000 --> 00:07:43,950 In fact, it can be passed 185 00:07:43,950 --> 00:07:46,290 in any container that can be iterated over 186 00:07:46,290 --> 00:07:49,260 so long as the logic of the lambda body can be applied 187 00:07:49,260 --> 00:07:51,180 to the contents of the container. 188 00:07:51,180 --> 00:07:52,140 You might also notice 189 00:07:52,140 --> 00:07:55,590 that the type specifier for the for loop range declaration 190 00:07:55,590 --> 00:07:57,660 has changed to auto as well. 191 00:07:57,660 --> 00:08:00,300 This is necessary if we want the for loop to be able 192 00:08:00,300 --> 00:08:02,700 to iterate over whatever data type is contained 193 00:08:02,700 --> 00:08:04,950 within the scores container. 194 00:08:04,950 --> 00:08:08,490 You can see from this example how useful the auto keyword is 195 00:08:08,490 --> 00:08:10,740 when implementing lambda expressions. 196 00:08:10,740 --> 00:08:13,380 So going forward, we'll be using them regularly 197 00:08:13,380 --> 00:08:15,840 as lambda parameter type specifiers. 198 00:08:15,840 --> 00:08:19,260 Just remember auto is not an actual type. 199 00:08:19,260 --> 00:08:21,150 It's an instruction telling the compiler 200 00:08:21,150 --> 00:08:22,803 to deduce the actual type. 201 00:08:23,670 --> 00:08:25,860 One of the best things about lambda expressions 202 00:08:25,860 --> 00:08:29,910 is their ability to be passed into functions as parameters. 203 00:08:29,910 --> 00:08:33,720 In C++ 14, there are two ways in which we can do this. 204 00:08:33,720 --> 00:08:36,150 The first is by passing a lambda expression 205 00:08:36,150 --> 00:08:37,350 as a function object 206 00:08:37,350 --> 00:08:39,753 using the standard library's functional header. 207 00:08:40,620 --> 00:08:43,049 We can see this done in the first example 208 00:08:43,049 --> 00:08:46,170 as the function foo takes as its parameter 209 00:08:46,170 --> 00:08:48,000 the function object l. 210 00:08:48,000 --> 00:08:50,160 The void type specifier represents 211 00:08:50,160 --> 00:08:52,260 the return type of the function object, 212 00:08:52,260 --> 00:08:54,570 and the integer type specifier represents 213 00:08:54,570 --> 00:08:56,790 the function object's parameter type. 214 00:08:56,790 --> 00:08:57,630 In this case, 215 00:08:57,630 --> 00:09:00,600 the function l takes as its parameter an integer, 216 00:09:00,600 --> 00:09:03,720 for example, 10, and returns nothing. 217 00:09:03,720 --> 00:09:06,870 The second way of passing a lambda expression to a function 218 00:09:06,870 --> 00:09:09,060 is as a function pointer. 219 00:09:09,060 --> 00:09:11,070 In the second example, the function foo 220 00:09:11,070 --> 00:09:14,970 takes as its parameter a pointer to the function l. 221 00:09:14,970 --> 00:09:17,820 Again, the void type specifier represents 222 00:09:17,820 --> 00:09:19,590 the return type of the function, 223 00:09:19,590 --> 00:09:21,810 and the integer type specifier represents 224 00:09:21,810 --> 00:09:23,790 the function's parameter type. 225 00:09:23,790 --> 00:09:27,240 In C++ 20, we can do away with the restrictiveness 226 00:09:27,240 --> 00:09:30,360 of having to declare the return and parameter types. 227 00:09:30,360 --> 00:09:33,390 We can simply use the auto keyword to tell the compiler 228 00:09:33,390 --> 00:09:35,883 to deduce both the return type and the parameter type 229 00:09:35,883 --> 00:09:38,103 of the passed lambda expression. 230 00:09:39,307 --> 00:09:41,910 In addition to using lambda expressions 231 00:09:41,910 --> 00:09:43,740 as function parameters, 232 00:09:43,740 --> 00:09:47,070 we can also have functions return lambda expressions. 233 00:09:47,070 --> 00:09:50,370 Similar to how we can pass lambda expressions to functions, 234 00:09:50,370 --> 00:09:51,300 we can return them 235 00:09:51,300 --> 00:09:54,270 as either function objects, function pointers, 236 00:09:54,270 --> 00:09:55,860 or by using the auto keyword 237 00:09:55,860 --> 00:09:58,920 to instruct the compiler to deduce the return type. 238 00:09:58,920 --> 00:10:01,410 You'll notice that the syntax of the second example 239 00:10:01,410 --> 00:10:04,200 which returns a function pointer's a little strange. 240 00:10:04,200 --> 00:10:06,180 This is old-style C syntax 241 00:10:06,180 --> 00:10:08,100 that has survived through generations 242 00:10:08,100 --> 00:10:09,930 for backward compatibility, 243 00:10:09,930 --> 00:10:11,850 but you shouldn't give it too much attention. 244 00:10:11,850 --> 00:10:14,130 In modern C++, if you want to return 245 00:10:14,130 --> 00:10:16,470 a lambda expression from a function, 246 00:10:16,470 --> 00:10:17,790 you'll most likely return them 247 00:10:17,790 --> 00:10:21,300 as either a function object or by using the auto keyword. 248 00:10:21,300 --> 00:10:23,010 So here you see three different ways 249 00:10:23,010 --> 00:10:24,960 to achieve the same result. 250 00:10:24,960 --> 00:10:25,860 What would it look like 251 00:10:25,860 --> 00:10:28,620 to actually call and use these functions? 252 00:10:28,620 --> 00:10:33,000 It's simple. All three versions use the exact same way. 253 00:10:33,000 --> 00:10:34,290 First, we call foo 254 00:10:34,290 --> 00:10:36,840 and assign its return value to a variable. 255 00:10:36,840 --> 00:10:39,150 Then we use the variable to execute the function 256 00:10:39,150 --> 00:10:42,120 and pass any parameters into it that it needs. 257 00:10:42,120 --> 00:10:43,740 In this case, we're passing a 10, 258 00:10:43,740 --> 00:10:45,750 and the 10 is displayed as a result. 259 00:10:45,750 --> 00:10:47,340 Examples of why you might want 260 00:10:47,340 --> 00:10:48,930 to return a lambda from a function 261 00:10:48,930 --> 00:10:52,080 are best explained using stateful lambda expressions, 262 00:10:52,080 --> 00:10:53,880 so we'll wait and cover that. 263 00:10:53,880 --> 00:10:55,530 In the meantime, let's go back 264 00:10:55,530 --> 00:10:58,530 to looking at lambda expressions as function parameters 265 00:10:58,530 --> 00:11:01,530 and see how we can call a function with a lambda expression 266 00:11:01,530 --> 00:11:03,480 as the pass parameter. 267 00:11:03,480 --> 00:11:06,180 In the first example, we can see that the lambda expression 268 00:11:06,180 --> 00:11:09,003 is defined within the function call to foo. 269 00:11:09,870 --> 00:11:10,860 This is a common way 270 00:11:10,860 --> 00:11:13,140 of passing lambda expressions to functions 271 00:11:13,140 --> 00:11:15,963 since in most cases they're only ever passed once. 272 00:11:16,950 --> 00:11:19,080 If a lambda will be used more than once, 273 00:11:19,080 --> 00:11:21,630 it may be beneficial to assign it to a variable 274 00:11:21,630 --> 00:11:23,700 so that it can be passed to multiple functions 275 00:11:23,700 --> 00:11:25,080 and called independently 276 00:11:25,080 --> 00:11:27,630 without having to define the lambda each time. 277 00:11:27,630 --> 00:11:29,910 In this case, the lambda can be passed to a function 278 00:11:29,910 --> 00:11:32,310 by passing the variable it was assigned to, 279 00:11:32,310 --> 00:11:33,960 as seen in the second example. 280 00:11:33,960 --> 00:11:36,240 Now, let's take a look at why we might want 281 00:11:36,240 --> 00:11:38,700 to pass a lambda expression to a function 282 00:11:38,700 --> 00:11:42,063 with a simple but powerful example using a predicate lambda. 283 00:11:42,939 --> 00:11:44,520 Before we get started, 284 00:11:44,520 --> 00:11:46,950 let me explain what a predicate lambda is. 285 00:11:46,950 --> 00:11:48,960 A predicate is a C++ function 286 00:11:48,960 --> 00:11:50,520 that takes any number of arguments 287 00:11:50,520 --> 00:11:52,293 and returns a boolean value. 288 00:11:53,130 --> 00:11:55,950 So naturally it follows that a predicate lambda is a lambda 289 00:11:55,950 --> 00:11:58,020 that implements this functionality. 290 00:11:58,020 --> 00:12:00,900 This may seem like a simple concept, and it is, 291 00:12:00,900 --> 00:12:04,080 but this is where the true power of lambdas lies. 292 00:12:04,080 --> 00:12:07,170 In this example, we have a function called print_if 293 00:12:07,170 --> 00:12:10,230 that takes as its parameters an integer vector 294 00:12:10,230 --> 00:12:13,800 and a predicate lambda that's passed as a function pointer. 295 00:12:13,800 --> 00:12:16,200 In this case, the predicate lambda is used to determine 296 00:12:16,200 --> 00:12:19,170 which elements of the integer vector to display. 297 00:12:19,170 --> 00:12:20,550 Within the main function, 298 00:12:20,550 --> 00:12:23,550 print_if is called with the integer vector nums 299 00:12:23,550 --> 00:12:26,010 and two different predicate lambdas. 300 00:12:26,010 --> 00:12:27,570 The first predicate lambda 301 00:12:27,570 --> 00:12:31,740 returns true if the parameter x is even and false otherwise. 302 00:12:31,740 --> 00:12:33,480 So when it's passed to the print_if, 303 00:12:33,480 --> 00:12:36,033 the even value of nums will be displayed. 304 00:12:36,960 --> 00:12:38,340 The second predicate lambda 305 00:12:38,340 --> 00:12:41,730 returns true if the parameter x is odd and false otherwise. 306 00:12:41,730 --> 00:12:43,860 So when it's passed into the print_if, 307 00:12:43,860 --> 00:12:46,920 the odd values of nums will be displayed. 308 00:12:46,920 --> 00:12:49,530 You can see that the same print_if function can be used 309 00:12:49,530 --> 00:12:51,480 to display different elements of the vector 310 00:12:51,480 --> 00:12:55,110 depending on the predicate lambda that's passed into it. 311 00:12:55,110 --> 00:12:58,290 This exemplifies the predominant use of lambda expressions 312 00:12:58,290 --> 00:13:00,390 and why they're so powerful. 313 00:13:00,390 --> 00:13:01,830 As we'll see later, 314 00:13:01,830 --> 00:13:03,720 predicate lambdas are extremely important 315 00:13:03,720 --> 00:13:06,090 when using the standard template library functions 316 00:13:06,090 --> 00:13:09,330 and algorithms such as sort or for each 317 00:13:09,330 --> 00:13:12,090 which require a predicate parameter. 318 00:13:12,090 --> 00:13:14,970 In the next video, we'll go over to the IDE 319 00:13:14,970 --> 00:13:17,490 and we'll run some of these examples and live code. 320 00:13:17,490 --> 00:13:20,250 I'll mark them up so you can see exactly what's happening. 321 00:13:20,250 --> 00:13:21,273 I'll see you there.