CPSC170
Fundamentals of Computer Science II

Lab 19

Prelab video

Function Templates

You've probably written functions where the only difference among the functions is the type of its arguments. Consider the following functions. The functions print a subinterval of a vector of doubles and a vector of integers, respectively.


void print(const vector<double>& vec, int start, int stop) {
   for (int i = start; i < stop; i++) {
      cout << vec[i] << " ";
   }
}

void print(const vector<int>& vec, int start, int stop) {
   for (int i = start; i < stop; i++) {
      cout << vec[i] << " ";
   }
}

As you can see, both functions are identical with the exception of the type of vec. It is a waste of time and energy to rewrite such code multiple times. So, we get the compiler to do it for us. This is where function templates come in. A function template, as its name suggest, is a template for a function. It isn't an actual function that can be compiled into machine code. Let's write a template function that can be used to create the above functions.


template <typename T>
void print(const T& vec, int start, int stop) {
   for (int i = start; i < stop; i++) {
      cout << vec[i] << " ";
   }
}

T is the template parameter. To make a function that can be compiled, the compiler only needs to substitute T for an actual type. There's nothing special about the name T. We could have used any other valid identifier. Usually the template parameter is give a logical name i.e., a name that suggests the types we expect the template parameter to be filled by. For example, RandomIterator is a common name used in the standard template library. The name RandomIterator tells us that the function template only works when given a type that supports the operations that can be performed on a random access iterator. Operations such as ++, --, [], and so on.

A function template can be called like any other function, we can also specify the exact function we want by specifying the template as in the following:
print<vector<double>>(vec). This line of code will cause the creation of the first function presented above. When we don't specify the template parameter, the complier infers a type based on the arguments given to the function. If the compiler is unable to figure it out, you'll get compiler error.

Templates are a very powerful tool in C++. We are only scratching the surface. Next lab we will look at template classes.

Exercise

Create a template function that takes two random access iterators start, end. It should sort all the number in the range [start, end). Your function should work with both pointers to an array and iterators to a container that has randomaccess iterators. Make appropriate pre/post comments. Your precomment should include the assumption that the iterators/pointers given to the function are valid, with start <= end.

Work on Friday's assignment. Next lab we will look at class templates.