1 00:00:05,340 --> 00:00:09,720 In this video, we'll look at what it means for an enumeration to be UN scoped. 2 00:00:09,990 --> 00:00:16,170 In the last video we looked at the structure and syntax of an enumeration and said that an enumerations 3 00:00:16,170 --> 00:00:17,670 key defines its scope. 4 00:00:17,970 --> 00:00:23,370 So far we've only seen the singular enum key use, and so you won't be surprised to hear that this key 5 00:00:23,370 --> 00:00:25,710 implements an scoped enumeration. 6 00:00:26,890 --> 00:00:29,620 But what does it mean for an enumeration to be on scoped? 7 00:00:29,830 --> 00:00:35,050 When an enumeration is scoped, it's enumerators are unqualified and they're visible throughout the 8 00:00:35,050 --> 00:00:38,040 entire scope in which the enumeration was declared. 9 00:00:38,050 --> 00:00:43,810 This means that if we want to use an enumerations enumerators, it's not necessary to specify which 10 00:00:43,840 --> 00:00:46,420 enumeration the enumerators belong to. 11 00:00:46,540 --> 00:00:47,620 Seems great, right? 12 00:00:47,620 --> 00:00:48,790 Let's work for us. 13 00:00:48,790 --> 00:00:52,150 But as we'll see later, this can sometimes cause issues. 14 00:00:52,150 --> 00:00:54,850 And this is why scoped enumerations are so useful. 15 00:00:54,850 --> 00:00:58,930 In the meantime, let's look at some common uses of scoped enumerations. 16 00:01:01,080 --> 00:01:06,930 One of the most common uses of enumerations is as conditionals and control structures such as if and 17 00:01:06,930 --> 00:01:07,890 switch statements. 18 00:01:08,310 --> 00:01:13,740 As we saw with the rocket launch example, by using an enumeration to represent the different states 19 00:01:13,740 --> 00:01:19,050 and sequences of the launch, we can create a readable control structure using if statements. 20 00:01:19,350 --> 00:01:25,050 Now suppose the ordering of control is reversed as seen here, so that the first condition evaluated 21 00:01:25,050 --> 00:01:30,300 is whether the state is nominal and the last condition evaluated is whether the state is engine failure. 22 00:01:30,990 --> 00:01:36,300 Can you think of any reason why this series of if L statements might not be the best implementation 23 00:01:36,300 --> 00:01:37,770 for our control structure? 24 00:01:38,920 --> 00:01:42,850 To understand why we might want to implement a different control structure. 25 00:01:42,850 --> 00:01:47,350 Let's imagine that state returned from the function gets state is engine failure. 26 00:01:47,680 --> 00:01:53,920 Obviously we want to initiate the abort sequence as quickly as possible, but with the current implementation, 27 00:01:53,920 --> 00:01:59,410 we must first evaluate whether the state is nominal and then evaluate whether the state is inclement 28 00:01:59,410 --> 00:01:59,950 weather. 29 00:02:00,460 --> 00:02:05,830 Then only after each of those two states have been evaluated can we determine that the state is engine 30 00:02:05,830 --> 00:02:09,130 failure and finally initiate the abort sequence. 31 00:02:09,580 --> 00:02:11,270 I know what you're probably thinking. 32 00:02:11,290 --> 00:02:13,810 The extra time taken has to be negligible. 33 00:02:13,810 --> 00:02:17,170 And for small control structures like this, it's certainly true. 34 00:02:17,560 --> 00:02:22,960 But what if instead we were evaluating 100 different states and again, the engine failure state is 35 00:02:22,960 --> 00:02:24,220 evaluated last. 36 00:02:24,370 --> 00:02:28,180 That extra time taken in this case might not be so negligible. 37 00:02:29,080 --> 00:02:34,180 You may think to simply reorder the condition evaluations of the control structure, but we often want 38 00:02:34,180 --> 00:02:40,390 equal access time for each of our control evaluations, meaning we want the nominal state to be evaluated 39 00:02:40,390 --> 00:02:44,950 as quickly as possible, as well as the engine failure state and so forth. 40 00:02:45,250 --> 00:02:48,850 So is there a way we can do this using if statements? 41 00:02:48,940 --> 00:02:49,990 Unfortunately not. 42 00:02:49,990 --> 00:02:52,120 But we can do it using switch statements. 43 00:02:53,880 --> 00:02:58,260 Switch statements are by far the most popular control structure used with enumerations. 44 00:02:58,500 --> 00:03:04,200 This is not only because they provide better readability than EPFL statements, but also because for 45 00:03:04,200 --> 00:03:10,020 five or more cases generally they are implemented as jump tables which provide equal access time for 46 00:03:10,020 --> 00:03:10,920 all cases. 47 00:03:11,460 --> 00:03:16,380 This means that regardless of where we position the nominal and engine failure states in the control 48 00:03:16,380 --> 00:03:19,290 structure, they'll be evaluated in equal time. 49 00:03:20,470 --> 00:03:24,760 It should be noted, though, that we can only use switch statements with the enumeration so long as 50 00:03:24,760 --> 00:03:28,780 the enumerators we use as switch cases have unique values. 51 00:03:29,140 --> 00:03:34,150 Otherwise, the switch will not be able to discern between its cases and the code won't compile. 52 00:03:36,670 --> 00:03:41,830 As we saw with our accidental launch scenario, we might want the user to initialize enumeration type 53 00:03:41,830 --> 00:03:42,340 variable. 54 00:03:43,230 --> 00:03:48,510 Unfortunately, we can't use the standard C in command with the extraction operator because the extraction 55 00:03:48,510 --> 00:03:53,070 operator has no knowledge of what a state type variable is or how to deal with it. 56 00:03:54,030 --> 00:03:56,490 Thankfully, we have two methods to deal with this. 57 00:03:56,670 --> 00:04:02,730 The first is to extract the user input value into a type that the extraction operator does know about 58 00:04:02,730 --> 00:04:05,280 and then cast it to the state type variable. 59 00:04:05,730 --> 00:04:10,280 The second is to overload the extraction operator to deal with state type variables. 60 00:04:10,290 --> 00:04:12,000 Let's take a look at both of these. 61 00:04:15,480 --> 00:04:20,880 Here we can see the first method which reads the user input into a temporary variable, which is then 62 00:04:20,880 --> 00:04:22,710 cast to a state type variable. 63 00:04:23,250 --> 00:04:28,800 When we declare the type of the temporary variable, in some cases the underlying type of an enumeration 64 00:04:28,800 --> 00:04:30,330 might not be obvious. 65 00:04:30,510 --> 00:04:34,500 So we can use the class template underlying type T to deduce it. 66 00:04:34,860 --> 00:04:40,170 In this case, the underlying type of the state enumeration is integer, so the type of the user input 67 00:04:40,170 --> 00:04:42,270 variable will also be integer. 68 00:04:42,840 --> 00:04:48,150 It's important to note that when we cast variables to enumeration types, the value of the variable 69 00:04:48,150 --> 00:04:49,380 does not change. 70 00:04:49,410 --> 00:04:54,420 This means that there's no guarantee that the cast state enumeration type variable will have a value 71 00:04:54,420 --> 00:04:57,540 corresponding to the enumerations enumerators. 72 00:04:59,220 --> 00:05:04,290 For example, if the user were to enter the value three, it would be cast to the state type variable 73 00:05:04,290 --> 00:05:05,970 state with no issues. 74 00:05:06,330 --> 00:05:10,950 Obviously this is not what we want since three does not correspond to any state enumerator. 75 00:05:11,700 --> 00:05:16,710 Our only recourse in this situation is to implement our own checks to ensure that the variable we're 76 00:05:16,710 --> 00:05:21,690 casting has a value corresponding to one of the enumerations enumerators. 77 00:05:23,050 --> 00:05:28,000 This is usually done by using a switch statement with the condition being the variable to be tested 78 00:05:28,000 --> 00:05:31,150 and the case is being each of the enumerations enumerators. 79 00:05:32,260 --> 00:05:34,690 There are many ways to perform these kinds of checks. 80 00:05:34,690 --> 00:05:39,220 But the important thing to remember is that you're responsible for ensuring that a variable cast to 81 00:05:39,220 --> 00:05:42,850 an enumeration type will have a valid enumerator value. 82 00:05:43,360 --> 00:05:48,250 In an example like this, you may want to set the output stream to a failed state in the case of an 83 00:05:48,250 --> 00:05:49,150 invalid state. 84 00:05:51,120 --> 00:05:56,640 The second method of reading user input values into enumeration types is by overloading the extraction 85 00:05:56,640 --> 00:05:57,300 operator. 86 00:05:57,750 --> 00:06:03,330 Using this method, we overload the extraction operator to take as parameters a reference to the input 87 00:06:03,330 --> 00:06:07,860 stream and a reference to the state variable that the user input will be read into. 88 00:06:08,670 --> 00:06:14,430 It's important that we declare it enumeration in the same scope as any function referencing the enumeration 89 00:06:14,430 --> 00:06:15,630 or its enumerators. 90 00:06:16,380 --> 00:06:21,900 This is to ensure that the enumeration type and its enumerators can be accessed from within the function. 91 00:06:22,500 --> 00:06:28,680 In this case, we've declared the state enumeration in the same global namespace that contains the overloaded 92 00:06:28,680 --> 00:06:30,450 extraction operator function. 93 00:06:30,450 --> 00:06:31,850 Within the function. 94 00:06:31,860 --> 00:06:37,080 Again, we have declared a temporary user input variable with the same type as the underlying type of 95 00:06:37,080 --> 00:06:38,040 the enumeration. 96 00:06:38,370 --> 00:06:44,340 Next, the user's input is extracted from the input stream and assigned to the temporary variable, 97 00:06:44,340 --> 00:06:49,350 which is then checked to ensure that its value corresponds to a valid state enumerator. 98 00:06:49,770 --> 00:06:54,080 If it does, the temporary variable is cast to the reference state variable. 99 00:06:54,090 --> 00:06:55,120 If it doesn't. 100 00:06:55,140 --> 00:06:59,370 The user is displayed a message informing them that they have not entered a valid state. 101 00:06:59,970 --> 00:07:03,150 Finally, the input stream is returned to the calling function. 102 00:07:03,420 --> 00:07:08,760 As you may have noticed, this method is identical to the first, but this time we've implemented it 103 00:07:08,760 --> 00:07:10,860 as an overloaded extraction operator. 104 00:07:10,980 --> 00:07:14,130 This is so we can write clean readable code like this. 105 00:07:15,110 --> 00:07:19,520 Now that we've seen how to use see in with enumerations, let's switch our focus to see how we can use 106 00:07:19,520 --> 00:07:21,140 see out with the durations. 107 00:07:23,270 --> 00:07:29,200 To display enumeration type variables, we can use the standard, see out and the insertion operator 108 00:07:29,210 --> 00:07:30,200 when we do so. 109 00:07:30,200 --> 00:07:36,500 The enumeration type variable is implicitly converted to its underlying type and its value is displayed. 110 00:07:37,040 --> 00:07:42,410 This means that when we display enumeration type variables, it's always there value that's displayed 111 00:07:42,410 --> 00:07:44,360 and never there enumerator name. 112 00:07:44,660 --> 00:07:50,450 This makes sense since an enumerators name isn't a string but simply a name used to identify its value 113 00:07:50,450 --> 00:07:51,440 within the code. 114 00:07:53,240 --> 00:07:57,470 Sometimes it may be useful to display the name of the enumeration type variable. 115 00:07:57,680 --> 00:08:03,170 And so to accomplish this, we can implement a simple switch statement using the variable as the condition 116 00:08:03,170 --> 00:08:06,080 and its cases being the enumerations enumerators. 117 00:08:06,470 --> 00:08:11,630 As you may have guessed, we could even implement this functionality by overloading the insertion operator. 118 00:08:15,490 --> 00:08:21,160 In this case, we overload the insertion operator to take as parameters a reference to the output stream 119 00:08:21,160 --> 00:08:24,310 and a reference to the state variable whose name will be displayed. 120 00:08:25,050 --> 00:08:30,090 Again, it's important to declare the enumeration in the same namespace as the overloaded function so 121 00:08:30,090 --> 00:08:34,200 that the enumeration type and its enumerators can be accessed from within the function. 122 00:08:35,140 --> 00:08:36,820 Within the overloaded function. 123 00:08:36,820 --> 00:08:41,320 The reference state is compared to the enumerations enumerators and the appropriate enumerator name 124 00:08:41,320 --> 00:08:43,150 is inserted into the output stream. 125 00:08:43,659 --> 00:08:49,390 Finally, the output stream is returned to the calling function by overloading the insertion operator 126 00:08:49,390 --> 00:08:54,520 to display the names of state type variables, we can write clean readable code like this. 127 00:08:55,780 --> 00:09:00,910 Now that we've covered some of the most common uses and pitfalls of UN scoped enumerations, let's head 128 00:09:00,910 --> 00:09:03,400 over to the IDE and see some more examples. 129 00:09:05,580 --> 00:09:06,000 Okay. 130 00:09:06,000 --> 00:09:12,750 So I'm in the ID, I'm in the enumerations workspace and I'm in the UN scoped E Nums project. 131 00:09:13,380 --> 00:09:18,180 What I've done in this project is written three tests that exercise different kinds of functionalities 132 00:09:18,180 --> 00:09:20,520 for UN scoped enumerations. 133 00:09:20,520 --> 00:09:24,930 Right now I've got Test two and Test three commented out, so we're just running test one now. 134 00:09:24,930 --> 00:09:25,830 I've already built it in. 135 00:09:25,830 --> 00:09:27,630 The output is over here on the right. 136 00:09:27,630 --> 00:09:29,400 But let's look at the code that I wrote. 137 00:09:29,400 --> 00:09:31,020 So you get an idea of what's going on here. 138 00:09:31,350 --> 00:09:36,630 So the first thing I did was I created a enumeration and it's called direction and you can see it right 139 00:09:36,630 --> 00:09:37,260 there. 140 00:09:37,620 --> 00:09:41,610 Notice that it's un scoped and the enumerators are north, south, east and west. 141 00:09:41,610 --> 00:09:47,310 And as we know, this gets a zero, this gets a one, this gets two and West gets the three and that's 142 00:09:47,310 --> 00:09:49,230 automatically done by the compiler. 143 00:09:49,650 --> 00:09:54,330 Now the first thing we want to know is if we try to create another enumeration, let's say, called 144 00:09:54,330 --> 00:09:59,880 Street, that models different kinds of street names, for example, and we've got Main North Street, 145 00:09:59,880 --> 00:10:01,200 Elm Street and so forth. 146 00:10:01,200 --> 00:10:04,560 We can't do this because we've got North twice. 147 00:10:04,710 --> 00:10:07,680 And the compiler is going to say, I don't know what you're trying to do. 148 00:10:07,710 --> 00:10:09,150 You're trying to declare that. 149 00:10:09,150 --> 00:10:14,790 So this is one of the limitations as I mentioned in the slides with UN scoped enumerations and we can 150 00:10:14,790 --> 00:10:17,490 handle that with scoped enumerations in the next example. 151 00:10:17,490 --> 00:10:18,570 That's where we're at here. 152 00:10:18,570 --> 00:10:23,160 And let me just show you what's going on in this example here, I wrote a function. 153 00:10:23,160 --> 00:10:25,470 The function is called Direction to String. 154 00:10:25,470 --> 00:10:27,300 You can see the name of the function right there. 155 00:10:27,330 --> 00:10:34,890 It expects a direction parameter and depending on the enumerator of that direction, we're going to 156 00:10:34,890 --> 00:10:36,360 return a string. 157 00:10:36,360 --> 00:10:41,490 It's either going to be north, south, east or west, depending on what the case of that enumerator 158 00:10:41,490 --> 00:10:42,390 is right there. 159 00:10:43,080 --> 00:10:44,670 And as you can see, it's returning a string. 160 00:10:44,670 --> 00:10:49,500 So this is just a real handy utility function where you pass in a direction and it's going to return 161 00:10:49,500 --> 00:10:53,280 north, south, east, west or unknown direction as a string. 162 00:10:53,670 --> 00:10:55,500 So we've got that and here's the test. 163 00:10:55,500 --> 00:10:58,650 The test is really straightforward and you can see the output over here on the right. 164 00:10:58,830 --> 00:10:59,970 So let's walk through this. 165 00:10:59,970 --> 00:11:01,500 You can see exactly what I'm talking about. 166 00:11:01,890 --> 00:11:06,540 So the first thing we're doing is we're outputting test and that's the output you see right there. 167 00:11:06,750 --> 00:11:13,710 And we're creating a variable here called direction and that variable is of a direction type. 168 00:11:13,710 --> 00:11:17,370 Now remember, when we create an enumeration, we're creating a new type in the system. 169 00:11:17,370 --> 00:11:23,130 So this is very similar to doing something like int I and initializing it to zero, let's say in this 170 00:11:23,130 --> 00:11:23,580 case. 171 00:11:23,580 --> 00:11:27,570 So we're using a type, we're creating a variable and we're initializing it. 172 00:11:27,570 --> 00:11:28,530 Same thing. 173 00:11:28,530 --> 00:11:31,770 We're using the type, a new type that we've just created. 174 00:11:31,770 --> 00:11:36,620 When we created that enumeration, there is the variable name and there's the initialize here. 175 00:11:37,410 --> 00:11:38,370 So that's it. 176 00:11:38,370 --> 00:11:39,750 I've initialize the north. 177 00:11:39,750 --> 00:11:41,940 Remember what we had originally here? 178 00:11:41,940 --> 00:11:47,430 We had north was zero, south was one, west, east was two and west was three. 179 00:11:47,430 --> 00:11:51,000 So right now that's enumerator value is zero, right? 180 00:11:51,000 --> 00:11:52,440 That's the underlying value. 181 00:11:52,440 --> 00:11:56,970 So we're going to display direction and then we're just going to pass in direction to that overloaded 182 00:11:56,970 --> 00:11:57,990 operator right here. 183 00:11:58,260 --> 00:12:03,510 As far as that's concerned, this is an integer now scoped numerators work very differently. 184 00:12:03,510 --> 00:12:05,160 But let's just talk about scoped here. 185 00:12:05,160 --> 00:12:10,470 So this is going to display zero and that's what's happening here that I'm calling direction to string. 186 00:12:10,470 --> 00:12:15,930 I'm passing in direction that's going to convert it to a string as we saw in the function a minute ago. 187 00:12:15,930 --> 00:12:17,550 And it's going to display north. 188 00:12:18,240 --> 00:12:21,930 If we set the direction to West, it's going to do exactly the same thing. 189 00:12:21,930 --> 00:12:23,550 It's going to display three and then West. 190 00:12:23,550 --> 00:12:28,530 In this case, if we try to set the direction to five, for example, we're going to get a compiler 191 00:12:28,530 --> 00:12:30,510 error because five is not valid. 192 00:12:31,260 --> 00:12:34,110 Be very careful when you're casting enumerators. 193 00:12:34,320 --> 00:12:37,320 You could cast things that aren't there and that's a problem. 194 00:12:37,320 --> 00:12:38,250 So here's an example. 195 00:12:38,250 --> 00:12:41,940 Here I am casting a direction as my variable. 196 00:12:41,970 --> 00:12:45,000 I'm casting 100 to a direction type. 197 00:12:45,420 --> 00:12:47,820 The compiler assumes you know what you're doing. 198 00:12:47,850 --> 00:12:52,350 Remember, right now all we've got is zero, one, two and three in there, right north, south, east 199 00:12:52,350 --> 00:12:52,980 and west. 200 00:12:53,160 --> 00:12:58,230 But if you're doing a cast like this, the compiler says, okay, I know you know what you're doing, 201 00:12:58,230 --> 00:13:01,770 so I'm going to let you do it and notice what this place displays 100. 202 00:13:01,770 --> 00:13:05,880 And then when we try to display the two string, we get unknown direction. 203 00:13:06,270 --> 00:13:09,960 And this is very, very similar to doing a static cast. 204 00:13:09,960 --> 00:13:11,610 So this is what's happening here. 205 00:13:11,610 --> 00:13:14,220 I just wrote this here so that you can understand what's happening. 206 00:13:14,220 --> 00:13:17,520 We come up here and you guys could try this out on your own. 207 00:13:17,520 --> 00:13:25,770 If we come up here to the top and we do something like North is one, you know, South is ten and then 208 00:13:25,770 --> 00:13:27,330 east and west would get 11. 209 00:13:27,330 --> 00:13:31,290 Then when you display these values here, you'll get different displaced. 210 00:13:31,710 --> 00:13:33,420 OC So that takes care of test one. 211 00:13:33,420 --> 00:13:35,370 You can play around with it and modify things. 212 00:13:35,370 --> 00:13:37,350 So let's switch over to Test two. 213 00:13:39,320 --> 00:13:39,650 Okay. 214 00:13:39,650 --> 00:13:45,770 So I've gone ahead and commented out test one and uncommon two doubt test two here and I've rerun the 215 00:13:45,770 --> 00:13:48,080 program and this is the output you can see over here. 216 00:13:48,080 --> 00:13:50,420 So now let's talk about what's going on in test two. 217 00:13:50,690 --> 00:13:52,760 Let me scroll back up to test two. 218 00:13:52,760 --> 00:14:00,050 So here's the enumeration that I'm using for the test two example in this case, I'm modeling a grocery 219 00:14:00,050 --> 00:14:02,120 item that's the enumeration I've created. 220 00:14:02,240 --> 00:14:04,880 And my numerators are milk, bread, apple and orange. 221 00:14:04,880 --> 00:14:08,120 And again, behind the scenes, we're getting a01, two, two and a three. 222 00:14:08,420 --> 00:14:13,550 And if we've got specific codes that we could use, and I believe I'm doing that a little bit later 223 00:14:13,550 --> 00:14:19,790 in the scoped enumeration, so let's say that milk is 350 and bread might be 150 or something like that. 224 00:14:19,790 --> 00:14:25,460 Those might be internal codes that we're using that represent the the code for milk, the code for bread 225 00:14:25,460 --> 00:14:26,150 and so forth. 226 00:14:26,150 --> 00:14:29,450 So if we need something like that, that's perfectly valid to do. 227 00:14:29,450 --> 00:14:34,100 But in this case, I'm just going to use the implicit initial zero one, two and three. 228 00:14:34,280 --> 00:14:39,680 Now, rather than having a function called to string like the one we created a little bit ago in test 229 00:14:39,680 --> 00:14:40,070 one. 230 00:14:40,070 --> 00:14:46,670 I want to overload the insertion operator because I want to be able to take these enumeration variables. 231 00:14:46,670 --> 00:14:52,520 They just put the right on an output stream and much easier than having to call a function and it blends 232 00:14:52,520 --> 00:14:54,560 right into the way C++ feels. 233 00:14:54,560 --> 00:14:57,110 So in this case, I've covered this in the class. 234 00:14:57,110 --> 00:15:01,130 If you're not familiar with overloading operators, there's a whole section in the course about it. 235 00:15:01,130 --> 00:15:07,820 So in this case, I'm overloading the insertion operator and I'm inserting a grocery item or the string 236 00:15:07,820 --> 00:15:11,540 representation of a grocery item into an output stream. 237 00:15:12,140 --> 00:15:13,340 So really simple. 238 00:15:13,340 --> 00:15:15,050 Right there is the grocery item. 239 00:15:15,050 --> 00:15:16,340 I'm switching off of it. 240 00:15:16,340 --> 00:15:18,710 We could have used it if else matter if we want. 241 00:15:18,710 --> 00:15:20,330 But in this case I'm using a switch. 242 00:15:20,360 --> 00:15:21,350 I'm switching off of it. 243 00:15:21,350 --> 00:15:24,830 If it's milk, I'm putting milk on the output stream. 244 00:15:24,920 --> 00:15:26,750 Bread, apple, orange. 245 00:15:26,750 --> 00:15:31,130 If it's something else, I'm writing invalid object and I'm returning the output stream. 246 00:15:31,130 --> 00:15:35,960 And now we also have a little test function here that I've written which can come in really handy. 247 00:15:35,960 --> 00:15:39,560 It's called is valid grocery item and it returns a boolean, right? 248 00:15:39,560 --> 00:15:40,670 A true false value. 249 00:15:40,670 --> 00:15:44,420 So given a grocery item, is it a valid enumerator? 250 00:15:44,420 --> 00:15:47,750 Well, it is a valid enumerator if it's one of the ones that I've defined. 251 00:15:47,750 --> 00:15:48,020 Right. 252 00:15:48,020 --> 00:15:49,220 Milk, bread, apple or orange. 253 00:15:49,220 --> 00:15:52,130 So in the case of any of these, I'm returning true. 254 00:15:52,880 --> 00:15:54,650 Otherwise I'm returning false. 255 00:15:54,830 --> 00:15:59,390 If I return false and I've got something else in there, I've probably cast it to something. 256 00:15:59,390 --> 00:16:02,810 And now I want to display a grocery list. 257 00:16:02,810 --> 00:16:04,310 And that's what Test two is all about. 258 00:16:04,310 --> 00:16:07,250 And test choose down here and I'll show you what that looks like in a moment. 259 00:16:07,250 --> 00:16:13,610 But the idea with this function is the function is called display grocery list and it expects a stood 260 00:16:13,610 --> 00:16:15,800 vector of grocery items. 261 00:16:16,160 --> 00:16:20,900 So basically a collection of grocery items and those guys are enumerations. 262 00:16:21,020 --> 00:16:23,330 So all I'm doing is I'm looping. 263 00:16:23,330 --> 00:16:26,060 You can see right here, I'm using a range based for loop. 264 00:16:26,210 --> 00:16:29,570 I'm looping over that grocery list right here. 265 00:16:29,960 --> 00:16:32,930 And for each grocery item, I'm displaying it. 266 00:16:32,930 --> 00:16:33,890 How am I displaying it? 267 00:16:33,890 --> 00:16:37,430 I'm using that overloaded operator that I just overloaded a moment ago. 268 00:16:38,060 --> 00:16:44,360 And I'm also keeping track of how many invalid items and how many valid items I've have using my is 269 00:16:44,360 --> 00:16:46,730 valid grocery item function that I wrote. 270 00:16:47,270 --> 00:16:48,470 So that's all we're doing. 271 00:16:48,470 --> 00:16:52,880 We're looping through each element in that list, we're displaying it and then we're checking, was 272 00:16:52,880 --> 00:16:54,200 it a valid item, yes or no? 273 00:16:54,200 --> 00:16:55,910 And keep counters for those. 274 00:16:55,910 --> 00:16:58,310 And then at the end we're just displaying some information. 275 00:16:58,700 --> 00:17:02,540 And now let's look at the actual example, which is right here. 276 00:17:02,540 --> 00:17:07,040 And in this case, this was actually pretty interesting because you can see I'm creating my shopping 277 00:17:07,040 --> 00:17:15,020 list here, which is a state vector of grocery items and I'm pushing back apple, apple, milk, orange. 278 00:17:15,500 --> 00:17:17,630 Those are all valid enumerators, right? 279 00:17:17,630 --> 00:17:22,490 The steward vector can contain those because it contains grocery items. 280 00:17:22,730 --> 00:17:25,040 What we're going to do is we're going to add them to that vector. 281 00:17:25,040 --> 00:17:25,849 That's what that's doing. 282 00:17:25,849 --> 00:17:28,610 That's what the pushback does in this case. 283 00:17:28,610 --> 00:17:33,170 If I try to say something like grocery item, item is 100, I'm going to get a compiler error. 284 00:17:33,290 --> 00:17:34,940 The compiler won't let me do that. 285 00:17:34,940 --> 00:17:41,240 However, if I create an integer called helicopter or some other silly name and initialize it to 100, 286 00:17:41,240 --> 00:17:45,680 and I pushed that it's going to let me push it, but it's going to be an invalid item when I display 287 00:17:45,680 --> 00:17:45,920 it. 288 00:17:46,880 --> 00:17:53,570 In this case, if I create a grocery item and initialize it to zero and this is a cast that's going 289 00:17:53,570 --> 00:17:54,380 to be milk, right? 290 00:17:54,380 --> 00:17:59,390 Because milk was the zero value enumerator in that enumeration. 291 00:17:59,390 --> 00:18:00,710 So that's what we're doing. 292 00:18:00,710 --> 00:18:02,240 We're just pushing some items on there. 293 00:18:02,240 --> 00:18:04,970 And then I'm displaying that list with the function I just showed you. 294 00:18:04,970 --> 00:18:07,010 So when this runs, this is what we get. 295 00:18:07,010 --> 00:18:10,190 We get apple, apple, milk, orange. 296 00:18:10,220 --> 00:18:11,360 You can see them right here. 297 00:18:11,360 --> 00:18:13,220 Apple, apple, milk, orange. 298 00:18:13,430 --> 00:18:19,130 Then we're going to get an invalid item, which is this guy right here, the helicopter, and then this 299 00:18:19,130 --> 00:18:19,940 guy is zero. 300 00:18:19,940 --> 00:18:21,260 So we're going to get milk again. 301 00:18:22,290 --> 00:18:27,630 And since we're keeping track of valid and invalid items, you can see here that we've got six total 302 00:18:27,630 --> 00:18:28,320 items. 303 00:18:28,320 --> 00:18:30,630 Five are valid and one is invalid. 304 00:18:30,630 --> 00:18:34,170 And that would be this guy right here, the helicopter. 305 00:18:36,080 --> 00:18:40,760 So that covers test two and again play around with this change some things, try some things out and 306 00:18:40,760 --> 00:18:42,090 you'll really get a feel for it. 307 00:18:42,130 --> 00:18:46,220 The important thing to understand here is just how much more readable this code becomes. 308 00:18:47,690 --> 00:18:48,110 Okay. 309 00:18:48,110 --> 00:18:50,100 So finally we're in test three. 310 00:18:50,140 --> 00:18:50,490 Okay. 311 00:18:50,510 --> 00:18:52,760 So let me show you what's going on in test three and test three. 312 00:18:52,760 --> 00:18:58,940 We've got an enumeration state that is the state which is either engine failure, inclement weather, 313 00:18:58,940 --> 00:19:00,740 nominal or unknown. 314 00:19:00,740 --> 00:19:05,480 Now, this is a common thing that you'll see a lot of times in enumeration is some sort of unknown or 315 00:19:05,510 --> 00:19:07,570 unspecified state. 316 00:19:07,580 --> 00:19:13,040 A lot of times it comes in real handy because sometimes we get strange values and it's nice to assign 317 00:19:13,040 --> 00:19:15,470 them to a known state, in this case an unknown state. 318 00:19:15,470 --> 00:19:16,730 So that's that. 319 00:19:16,730 --> 00:19:21,170 Then we've got a sequence which is the abort sequence, the whole sequence or the launch sequence, 320 00:19:21,170 --> 00:19:22,970 depending on what the state is. 321 00:19:22,970 --> 00:19:25,010 We execute a specific sequence. 322 00:19:25,010 --> 00:19:31,250 So what we've done here is we've got our stream extraction operator that we've overloaded and this is 323 00:19:31,250 --> 00:19:36,920 pretty neat because it allows the user to enter something and we're going to create a state variable 324 00:19:36,920 --> 00:19:37,430 from it. 325 00:19:37,430 --> 00:19:41,870 So in this case, we're going to use the underlying type and you can see that right there. 326 00:19:41,870 --> 00:19:43,190 That's the underlying type. 327 00:19:43,190 --> 00:19:46,730 We know that the underlying type for this enumeration is an INT. 328 00:19:46,730 --> 00:19:52,070 We could have used int user input just like this, but it's much better to use the underlying type because 329 00:19:52,070 --> 00:19:57,830 it could change in the future if someone assigns some initial enumerator value to one of those things. 330 00:19:57,830 --> 00:19:58,880 That's not an int. 331 00:19:59,150 --> 00:20:06,050 And what we're doing is we're reading that user input from the input stream, we're switching on it 332 00:20:06,350 --> 00:20:11,750 and depending on what it is in this case, if it's one of those things that we know about right engine 333 00:20:11,750 --> 00:20:18,380 failure, inclement weather, nominal or unknown, we're casting that user input to a state type and 334 00:20:18,380 --> 00:20:20,810 assigning it to state, which is that guy right there. 335 00:20:20,900 --> 00:20:25,190 Otherwise we're going to assign it to the state unknown because they've obviously entered something 336 00:20:25,190 --> 00:20:25,700 else. 337 00:20:25,700 --> 00:20:30,110 And the idea being if it's in an unknown state, we're not going to launch this rocket, we're going 338 00:20:30,110 --> 00:20:30,710 to abort. 339 00:20:30,710 --> 00:20:34,460 So we've got those three sequences you can see up here, abort, hold and launch. 340 00:20:34,880 --> 00:20:39,590 Here we are overloading the string insertion operator just like we did before. 341 00:20:39,590 --> 00:20:42,080 So given a C but for sequence in this case. 342 00:20:42,080 --> 00:20:48,170 So given a sequence, if it's abort, we're just going to display, abort, hold or launch depending 343 00:20:48,170 --> 00:20:49,730 on what the numerator value is. 344 00:20:50,240 --> 00:20:54,770 And then in the case of initiate, when we're calling initiate with a sequence, it's just going to 345 00:20:54,770 --> 00:20:58,340 display the sequence that's being initiated just so we can actually see it. 346 00:20:58,340 --> 00:21:03,110 And this is going to use the overloaded stream insertion operator right there. 347 00:21:04,200 --> 00:21:04,370 Okay. 348 00:21:04,440 --> 00:21:05,420 So here's test three. 349 00:21:05,430 --> 00:21:06,320 So take a look at this. 350 00:21:06,330 --> 00:21:07,280 It's pretty straightforward. 351 00:21:07,290 --> 00:21:09,450 I'm creating my state variable right here. 352 00:21:10,270 --> 00:21:12,520 And I'm reading that from the user. 353 00:21:12,560 --> 00:21:15,980 Now this is using our extraction opera that we just overloaded. 354 00:21:16,000 --> 00:21:21,430 You can see how neat this is because this feels just like anything else in C++, right? 355 00:21:21,910 --> 00:21:23,170 This is how we read integers. 356 00:21:23,170 --> 00:21:24,460 This is how we read strings. 357 00:21:24,460 --> 00:21:25,900 This is how we read a lot of things. 358 00:21:26,260 --> 00:21:30,040 However, this is a user defined type that we created state. 359 00:21:30,040 --> 00:21:36,340 So we have to overload the extraction operator so that we can write code like this depending on whatever 360 00:21:36,340 --> 00:21:42,130 state the user entered, if they entered engine failure or if it's unknown, right? 361 00:21:42,130 --> 00:21:43,210 They entered something else. 362 00:21:43,210 --> 00:21:45,310 We're going to initiate the abort sequence. 363 00:21:46,000 --> 00:21:49,960 If it's inclement weather, we're going to hold and if it's nominal, we're going to launch. 364 00:21:50,470 --> 00:21:54,730 So let's run this and I'll put in a zero, which is engine failure. 365 00:21:54,730 --> 00:21:56,830 And we're initiating the abort sequence, right? 366 00:21:56,830 --> 00:21:57,640 That's what we want. 367 00:21:57,640 --> 00:21:58,870 So let's try it with another one. 368 00:21:58,870 --> 00:22:00,040 Let's run it again. 369 00:22:00,040 --> 00:22:06,100 In this case will put in a one and we're holding because one is inclement weather. 370 00:22:06,100 --> 00:22:07,000 That's pretty cool. 371 00:22:07,740 --> 00:22:09,130 Let's try it again. 372 00:22:09,150 --> 00:22:10,800 Let's put in a chew this time. 373 00:22:11,710 --> 00:22:13,060 And we move this over here. 374 00:22:13,540 --> 00:22:14,650 We're going to put in a two. 375 00:22:14,680 --> 00:22:16,090 We're launching, right. 376 00:22:16,090 --> 00:22:18,400 Because two is nominal. 377 00:22:19,160 --> 00:22:21,660 And now let's put in something like 100 or something, right? 378 00:22:21,680 --> 00:22:26,130 Something that's definitely not a valid enumerator for the estate. 379 00:22:26,150 --> 00:22:29,240 So let's run this and it's put in 100. 380 00:22:29,570 --> 00:22:31,670 And what we want is we want to abort. 381 00:22:33,270 --> 00:22:34,590 And that's exactly what we get. 382 00:22:34,590 --> 00:22:36,510 The user input is not a valid launch date. 383 00:22:36,510 --> 00:22:41,040 So what we're doing is we're setting the state to unknown, which initiates that abort sequence right 384 00:22:41,040 --> 00:22:41,450 here. 385 00:22:41,460 --> 00:22:46,170 This is all well and good, but what's really important that you understand is look at that code. 386 00:22:46,170 --> 00:22:47,790 Look how readable this is. 387 00:22:48,000 --> 00:22:49,380 We're switching on the state. 388 00:22:49,380 --> 00:22:51,780 If the if it's engine failure unknown, we initiate abort. 389 00:22:51,780 --> 00:22:57,960 We're using these enumerators, which is so important instead of just having magic numbers and all kinds 390 00:22:57,960 --> 00:23:01,800 of weird things in our code that make things very, very difficult to understand. 391 00:23:02,550 --> 00:23:02,730 Okay. 392 00:23:02,820 --> 00:23:07,410 So I encourage you to play around with this code, change things around, understand it. 393 00:23:07,410 --> 00:23:11,880 The best way to learn this is just to get in that code and fiddle with it and change it around a little 394 00:23:11,880 --> 00:23:15,900 bit and add some new states and try different things in the next video. 395 00:23:15,900 --> 00:23:20,760 What we'll do is we'll talk about scoped enumerations and we'll see how much better they actually are.