We have seen how to construct simple classes to handle complex numbers and vectors. In both cases we chose to make the components double precision. If we later decided to work with single precision complex numbers, we would have to rewrite the class definition. If we wanted both precisions to coexist in the same calculation, we would need a separate name for each class.
Through the ``template'' feature C++ saves us the tedium of rewriting
the class definitions. Here is how it works for the simplest
version of mycomplex.h.
|
|
class in the angle brackets here is apt to be
confusing, because it has nothing to do with the classes we have been
discussing so far. It is just the way we signal to the compiler that
the label T is a substitution parameter that stands for
any datatype we might want to use later on to complete the definition.
Notice that T appears twice in the class declaration.
|
<double> which causes
double to replace every occurrence of T in
the template declaration. If, later on, we wanted to create a single
precision complex number, we could do it this way:
complex<float> b;The same template is used, but now with
float replacing
T. Note, however, we can no longer say, simply, complex c;. A suffix is always required.
If we tire of always writing complex<double> and complex<float>, we can create abbreviated names using a typedef statement as follows:
typedef complex<double> dcmplx;
typedef complex<float> fcmplx;
Then we can declare variables by their shortened type names as
follows:
dcmplx a;
fcmplx b;
The general form for the typedef statement is
typedef oldname newname;
These statements are usually collected at the top of the source file
along with the #include directives, or better still, they
are collected in header files.
Templates can also be used with function definitions. For example,
the cadd function that adds two complex numbers was
defined with the double precision complex type in mind. We can
generalize its definition as follows:
|
The function cadd has been templatized. For variety we
used the parameter FLT this time, but even if we had used
T again, it would not be confused with the same label
used in the class declaration above.
Here is how we use this class and this function.
|
cadd function call in the main
program
|
<double>. The compiler can
tell which version of cadd we intend by looking at the
arguments. They are both of type complex<double>, so it
concludes that we must have intended to replace T with
double in the function template to match the required
function signature.