CS210 Lab: Templates
Prelab Questions:
For a review of relevant topics click
here.
Highlights of This Lab:
Lab Exercise:
Click the little computer above for a detailed description.
For this excercise you will be asked to implement a function template that
will swap two values of any type.
1. What is a Template
A template is a generic function or class which can deal with arbitrary types of data.
Consider the linked list picture below.

There are integer numbers (4, 16, 23, and 55) in this linked list.
What if we wanted to have characters (or any other data type) as data into this structure,
as in the below diagram.

We could retype all of the code for the linked list class--changing
only the type.
Or, we could use a template class--a class which can be seen
as a generic class able to handle many types.
1.2 What are Some Advantages of Using Templates?
- saves you time retyping code
- promotes code reuse
- saves you errors (in mistakes made retyping)
1.3 There are two kinds of templates:
- function templates
- class templates
Let's consider function templates first.
2. Function Templates
Suppose we had the following function which returned the maximum of two
integer values passed to it:
#include <iostream>
using namespace std;
int maxi(int a, int b)
{
return a > b ? a : b ;
}
This condensed code makes use of the ?:
ternary operator, also referred to as the conditional operator.
The function above is equivalent to:
int maxi(int a, int b)
{
if (a > b)
return a;
else
return b;
}
This maxi function works fine for integers,
but what if we want to find the
maximum of two floating type numbers.
We could overload the function and retype the code replacing int
with float, or
we could use Function Templates.
2.1 Implementing Function Templates
Function templates are implemented like regular functions,
except they are prefixed with the keyword template. The following
demonstrates in red how we had modified the regular function maxi
to make it a function template:
#include <iostream>
using namespace std;
template <typename T>
T maxi(T a, T b)
{
return a > b ? a : b ;
}
(To see a side by side comparison of this function template with the regular
function, click
here)
You can note the following things:
- template: keyword used to indicate that this is a template function
- <typename T>:type parameters that are used to create a particular
instance of the function.
- typename: a keyword; a generic term for a type. You will also see the keyword class used the same way. There is no difference between the two in this context, but we prefer typename in this lab to avoid confusion with object oriented programming.
- T: a dummy type. This will be replaced by a
particular data type when an instance of the template is created.
This can be any name you chose; it does not have to be "T"
2.2 Using Template Functions
Using function templates is very easy: just call them like
regular functions. When the compiler sees an instantiation of the
function template, for example: the call maxi(10, 15) in function main,
the compiler generates a function maxi(int, int).
Similarly the compiler generates definitions for maxi(char,
char) and maxi(float, float) in this case.
#include <iostream>
using namespace std ;
//maxi returns the maximum of the two elements
template <typename T>
T maxi(T a, T b)
{
return a > b ? a : b ;
}
void main()
{
cout << "maxi(10, 15) = " << maxi(10, 15) << endl ;
cout << "maxi('k', 's') = " << maxi('k', 's') << endl ;
cout << "maxi(10.1, 15.2) = " << maxi(10.1, 15.2) << endl ;
}
Program Output
maxi(10, 15) = 15
maxi('k', 's') = s
maxi(10.1, 15.2) = 15.2
Function Prototypes
As a note, if you need to use a function prototype in your file, preceed
it with the template <typename T> specifier.
e.g.
template <typename T> T maxi(T & a, T & b);
3. Class Templates
Class templates come in handy when storing data in "containers"
(such as linked lists, stacks, and queues).
For each container,
the type of data may be different, but the methods of manupulating data
are the same.
Consider the integer linked list class, which may be represented by this code.
The problem with this class is that it handles only integers.
What if we want a linked list with other types (char,
float, etc)?
We could create separated classes.
For example:
- class LinkedListint (to handle integers),
- class LinkedListchar (to handle characters), and so on
OR, we could turn this
linked list into a class template and make it more generic.
3.1 Implementing a class template
There are three things to consider when implementing a class template:
(Here, red highlights the syntax specific to class templates)
- Creating a class template. The general form is shown below:
template <typename Ttype>
class Class_name
{
...
...
}
- Notice, again, the template keyword and the
use of <typename Ttype>.
The Ttype is a placeholder type that will be
specified when a class is instantiated.
- Defining member function templates.
Use the general form:
template <typename Ttype>
return_type Class_name<Ttype>::Function_name
{
...
...
}
- Notice, that the member function declaration is preceded by
template <typename Ttype >,
and there is an extra
<Ttype>
after the class name
- Creating a specific instance. Use the general form:
Class_name <type> obj;
- Where, type can be int,
char, double, or any
user-defined type
3.2 An example of a class template and its use
The following example is meant to get you more familiar with the syntax of
class templates. The red font highlights the syntax added for templates.
(To see a side by side comparison of this class template with an ordinary
class, click
here)
#include <iostream>
using namespace std;
//1. creating a class template
template <typename T>
class my_class
{
T i;
public:
my_class(T a);
void show();
};
//2. defining member function for class template
template <typename T>
my_class<T>::my_class(T a)
{
i=a;
}
template <typename T>
void my_class<T>::show()
{
cout << "i is: " << i << endl;
}
int main()
{
//3. creating specific instances
my_class <int> intobj(10);
my_class <char> charobj('A');
intobj.show();
charobj.show();
return 0;
}
Program Output
i is: 10
i is: A
In the definitions of intobj and
charobj, the data type is enclosed in angle brackets.
This data type is the actual parameter
(or argument) to the template.
At compile time, the compiler generates (instantiates) two
distinct class types and gives its own internal name to each type.
You might imagine that the definitions are transformed internally into
something like this:
- my_class_int intobj(10);
- my_class_char charobj('A');
In each of these versions (visualized as my_class_int and my_class_char),
the compiler has substituted an actual type (int and char, respectively)
for placeholder (T) in the my_class template.
4. Lab Exercise
Class Templates with multiple files