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.
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.