Vectors can be the parameters or the return types for functions. For now, we need to specify what type of vector the function accepts or returns (vector<int>, vector<string>, etc...). Later on we will learn how to make a βgenericβ function that can work with a vector that stores any type.
// total up all the values in numbers
int total(vector<int> numbers) {
int total = 0;
for (int x : numbers) {
total += x;
}
return total;
}
However, that version of the function would pass by value and copy the entire vector that was passed. It would be better to pass by const reference. Nothing other than the parameter needs to be changed:
// total up all the values in numbers
int total(const vector<int>& numbers) {
int total = 0;
for (int x : numbers) {
total += x;
}
return total;
}
To return a vector, we can declare the return type to be a vector<XXX> where XXX is the type of data in the vector. This function returns a new vector that is a copy of the one passed in which every element gets doubled:
In this version, we must take the vector parameter as a reference that is not const so we can modify the vector (line 7). Similarly, as we use a range-based loop to traverse the elements, we need to declare the element type to be an int& - a reference to an int - so that we are working with the actual element and not a copy of its value (line 9). Because the parameter is modified, there is nothing new to return from the function. So the return type is declared as void (line 7) and when it is called in main, there is no result to store (line 17). Because we passed by reference, all of the changes made to numbers in doubleValues really were made to myList that was passed in from main.
Of the two versions of doubleValues, the first one is probably the better choice. It is generally preferable to write pure functions that do not have side effects (like modifying parameters). Pure functions are easier to reason about and test since they always produce the same output for the same input and do not modify anything outside of the function.
The pure function will be less efficient since it makes a copy of the entire vector. But unless we are working with very large vectors or doing this operation many times in a performance-critical section of code, we probably should favor code clarity over efficiency.
You can use pass by value (e.g., vector<int>), to intentionally make a copy of the vector that is safe to modify. However, you could also just start with a const reference and make a copy of that.
Construct the makeEven function that makes a new vector by looping through vec to copy elements. Any element with an odd value get 1 added to make it even before it is copied.