In this lecture, we'll learn how to pass containers into functions and how to use those containers within functions. Although we'll demonstrate the pass by value mechanism with containers, you should always use the pass by reference mechanism with containers to avoid copying all the elements of the containers as you're passing an the argument into the function. For our starting code, I've implemented a couple of functions, one called the FillVector and one called the CalculateAverage. I'm going to scroll down to those now. So FillVector just fills this vector with the numbers 1, 2, and 3 and then this other function calculates the average of a vector that's passed in as an argument. Let's look at the FillVector function first. I'm going to call the FillVector function with my scores vector and then I'll print out the values in my scores vector. I'll write the code to do that and then we'll come back. This is just a simple for loop to print out the scores vector. Let's go ahead and run the code and see what happens. As you can see, there's nothing in the vector. What this demonstrates is that by default, even with containers C++ uses the pass by value mechanism. We know that if we want to change the value of one of the arguments we passed in, we need to pass by reference instead. Let's do that. Of course I need to change my full function definition as well and I'll scroll back up, and when I run the code, you see the vector actually gets filled in. As we discovered a couple of lectures ago, pass by reference, lets us change the arguments we pass in, and this is the way we needed to do it up until C++ 11. C++ 11 gives us one more mechanism that we can use and it's called the move mechanism or move semantics. Using move semantics is the appropriate way to programing C++ if you're using C++ 11 or later. Let me show you how we make that work. First of all, I'm going to say this function actually returns a vector of int, and I'm not going to pass anything in. I will grab this and move down to my function body. But now we no longer have this vector to fill in. So what we do is we declare a local variable and I'll just call it vector, and that'll make it easy. Now, I can add 1, 2, and 3 to this local variable, but at the very end of my function, I actually return this vector. When I do this, it actually uses those move semantics to move this vector into scores. There's no copying here, it's actually a move. So now when I call the function, I will take the result that's returned from the function and put it into my scores variable. When I run, we see that the scores vector gets filled in with 1, 2, 3 as expected. So in C++ 11 or later, you should use move semantics for containers so that your functions look like in general. The arguments are, the parameters are for information that you're passing into the function and those are often called in parameters and the result of the function is returned from the function. That way we avoid using what are called out perimeters. So that intermediate one where I had a pass by reference to the scores vector, I was changing that scores vector within the function. That was the way we needed to do it in the past, but we don't have to do it that way anymore in many cases, including when we're passing containers or returning containers. So that's the first function, and I showed you the first function uses pass by value by default as C++ does for parameters. Then we change that to pass by reference, which we learned about a couple of lectures ago. But then I showed you using move semantics, which is the right way to return containers from functions. Let's go ahead and average as well, so I'll set an average variable equal to calculate average and we know I need to pass in a vector and that scores and let's print out the average as well. I'll just say and average, and let's see what happens. As you can see the average is two which is expected with 1, 2, and 3. I want to show you one more thing. I passed the vector in by reference and I did that because I don't want to have to copy each element of the vector into a new vector, I won't pass by reference to avoid that copying. All I pass it is a reference to that variable. Remember now I have an alias, I have values that refers to that vector and I have scores that refers to that vector. I guess I should grab it here but it's the same scores, so we have two essentially variables referring to the same location in memory and that's all great. It sees be the copying and so on and it's all great unless I'm a dork and I do something like this, values zero equal 100. If I do that, when I run my code, you'll see that I've changed the first element of my scores vector to contain 100 rather than one. Of course that's why we pass by reference so that we can in fact change the value of our variable that we passed as an argument. But we don't want that to happen here. We want to make sure that the values vector can't be changed within this function. I know this feels like an artificial example, why on earth would you do that? There are lots of other subtle ways that you might change an argument or change a parameter here in the function where you didn't want the argument to be changed, so C++ provides us a mechanism to say, we do not want to actually be allowed to change this parameter. The way we do that is we say const, just as when we are defining a constant. We're telling the compiler we do not want this variable or constant to be able to be changed as we run our code. Adding that keyword here before the parameter tells the compiler you're not allowed to change the values vector inside the function and whatever data type you have as your perimeter, const works that way for all of them. Now we get a compilation error and as you can see, it says you can't assign to a variable that's a const. Providing the const keyword protects us from making a mistake, perhaps a more subtle mistake than this that changes the parameter which will also change the argument that we use to call the function if we pass by reference. We've removed this crazy code and we go to compile and we get this very confusing link error. Notice this is not a compilation error, this is happening in the linker after we've compiled and it's saying it can't find calculate average. The reason for that error is we added const here but we didn't add const to the function prototype. We add cons to the function prototype and the code compiles fine and we can run it again and we see we get the same results we got before except now we've protected ourselves from actually changing our vector inside our calculate average function. To recap, in this lecture you learned that C++ still uses the pass by value mechanism when containers are passed into a function. You learned how you can change the function header to use the pass by reference mechanism instead so we can change the container within the function. You learned that we can use the const keyword so that we're prohibited from changing the container when we're within the function even if we've used the pass by reference mechanism and you learned about move semantics which you should prefer to the pass by reference mechanism whenever it's possible.