|
C M S C 2 1 4 C o m p u t e r S c i e n c e I I F a l l 2 0 0 2 |
Rather than repeat the code in the function over and over, and making substitutions for each variable, you write a function, and call it with different variables.
This works fine when you want to plug in variables of different names but the same type.
What if you would like to do the same thing with different types?
For example, all linked list operations basically work the same on Node objects. The only thing that differs is the type of the data in the Node object, and what the comparison operation does on that type.
Wouldn't it be neat to generalize on the type, so you don't have to write the same code over and over again, where the only change is the type?
That's the purpose of templates. To allow you to write the code once and parameterize the type.
The general approach to templatizing is to have an example code before
For example, suppose you have a class that stores a dynamic array.
class MovieArrayList {
Movie * arr ;
int _size;
}
Instead of storing just movies, you want to store any type.
Then, you add the template prefix to the top.
template <class Data> // template prefix
class ArrayList {
Data * arr ;
int _size;
}
which consists of the word template then, in angle
brackets, the word class (or typename--the two
names are equivalent in this context), followed by an identifier.
The identifier is merely a variable name, but the variable
is actually a type name (thus, why some people use the keyword
typename).
Then, everywhere you see Movie, you replace by the typename, Data. Note: Data is not a real class. It is a variable name meant to be instantiated to a real class.
For example, if you have a toString() method, you may really intend to return a string even after templatizing. Similarly size() may return an int, even after templatizing.
Use this as a guide to converting to templatized functions.