(
from here )
Templatized Function
You can almost think of templates as macros.
In this case, 'T' is just a placeholder for the type or class used. First, 'T' becomes
int, then
long. It works because the
> operator is supported for the types being called.
#include <stdio.h>
template <class T>
T GetMax (T a, T b) {
T result;
result = (a>b)? a : b;
return (result);
}
int main () {
int i=5, j=6, k;
long l=10, m=5, n;
k = GetMax<int>(i, j);
printf("%d\n", k);
// Note, the compiler can automatically detect the type...this works just as well
k = GetMax(i, j);
printf("%d\n", k);
n = GetMax<long>(l, m);
printf("%d\n", n);
return 0;
}
Note, if you declare your function like this...
template <class T, class U>
T GetMax (T a, U b) {
return (a>b)? a : b;
}
...you can pass in 2 different types of parameters
Templatized Classes
#include <iostream.h>
template <class T>
class pair {
T value1, value2;
public:
pair(T first, T second)
{ value1 = first;
value2 = second;
}
T getmax();
template <class T>
T pair<T>::getmax()
{ T retval;
retval = value1 > value2 ? value1 : value2;
return retval;
}
int main()
{ pair <int> myobject(100, 75);
cout << myobject.getmax() << endl;
return 0;
}
Note how you have to declare the member function outside the class block. Without the
template part, the compiler doesn't know what
T is all about. If you're within the class block, however, you can declare it very simply like this...
...
T getmax()
{ T retval;
retval = value1 > value2 ? value1 : value2;
return retval;
}
...
Template Specialization
This little program makes me wonder if there is some kind of cool C++ technique waiting to be exploited here. Not only do we have a case where calling the
modulus function with
int does a different thing than
float (or anything else for that matter), but we have added a function that only
int has. On the other hand, you have to re-define every methond - there's no inheiritance!
In a sense, the specialized template is really a distinct class of its own. That is, not only does it not inheirit anything, but it does not have to have the same methods. There is no interface protection - an implementer could do whatever he wanted and leave out half the methods. Though the objects are declared as
pair this seems to be just a compiler convenience as there is no intermixing or binding between
pair <int> and
pair <float>
template <class T>
class pair {
T value1, value2;
public:
pair(T first, T second)
{ value1 = first;
value2 = second;
}
T modulus() { return 0;}
};
class pair <int> {
int value1, value2;
public:
pair(int first, int second)
{ value1 = first;
value2 = second;
}
int modulus();
void foo()
{ printf("hi there\n");
}
};
int pair<int>::modulus()
{ return value1 % value2;
}
int main()
{ pair <int> myobject(100, 75);
pair <float> myobject2(10.0, 7.5);
cout << myobject.modulus() << endl;
myobject.foo();
cout << myobject2.modulus() << endl;
// can't do!
// myobject2.foo();
return 0;
}
--
MattWalsh - 20 Sep 2004