When you want to give a new name to some type of thing, for example:
1 2
|
typedef unsigned int uint;
// the type 'unsigned int' is now also known by the alias 'uint'
|
it can be done. The
typedef statement has a global effect -- everything after it recognizes the new type name as an alias for the other type.
In generic programming, the idea is to extend this power in two ways:
1. make a typedef local to a specific construct (or function)
2. make it work on multiple types
To explain those, here is a simple example:
1 2 3 4 5 6 7 8 9 10
|
// A handy function to add a vector of integers
//
int SumIntVector( const vector <int> & v )
{
vector <int> ::const_iterator i;
int result = 0;
for (i = v.begin(); i != v.end(); ++i)
result += *i;
return result;
}
|
However, suppose we have a vector of floats that we wish to sum? We'd have to write yet another function:
1 2 3 4 5 6 7 8 9 10
|
// A handy function to add a vector of floats
//
float SumFloatVector( const vector <float> & v )
{
vector <float> ::const_iterator i;
float result = 0.0;
for (i = v.begin(); i != v.end(); ++i)
result += *i;
return result;
}
|
You'll notice that there are only two things different between the functions: the
type of the thing being summed (
int or
float), and the literal constant used as the initial value (line 6).
Consider that this function might be useful to sum a vector of chars, or any other type where addition is defined on it. To do this, we can create a
template function that has the type of object it operates over automatically
typedefed:
1 2 3 4 5 6 7 8 9
|
template <typename Summable>
Summable SumVector( const vector <Summable> & v )
{
typename vector <Summable> ::const_iterator i;
Summable result = Summable();
for (i = v.begin(); i != v.end(); i++)
result += *i;
return result;
}
|
The type 'Summable' doesn't actually exist. It is typedefed when used (condition 2). And it is only typedefed in the definition of the template function (condition 1).
In fact, the function itself doesn't exist until it is used. Hence, it is a
template used by the compiler to create a function when needed.
So, in your above posting, the
Comparable type is an alias for some type of thing that can be compared (using the
less template function, which is a fancy way of writing the < operator); and the
Comparator type is an alias for a function that compares two
Objects. Such function must exist when you call (and thus cause the compiler to create) the two-argument
insertionSort() function.
Hope this helps.