C++ Reference Material
Templates: Functions and Classes
This page gives a very brief overview of both template functions and template classes. The C++ Standard Template Library makes extensive use of both, of course, so you need to have a reasonable grasp of the general idea of templates before looking at that library in detail. In general using templates is often referred to as generic programming, because one is writing code to deal with generic types. The code that one writes in a template is code that can do whatever it does with data having any number of different types, and the actual type on any given occasion is specified when the template function or template class is actually created (or instantiated) and one or more specific types are passed as parameters.
void swap(int& first, int& second); void swap(double& first, double& second); void swap(string& first, string& second);Each of these functions does the same thing, namely, it exchanges the values of two variables of the given type. Moreover, if you had variables of other data types that needed to be exchanged you could write additional swap() functions.
But this clearly involves using essentially the same lines of code over and over again. This is the sort of thing programmers like to avoid, since it runs counter to their pursuit of the Holy Grail of code reuse.
And so ... template functions to the rescue. Instead of writing all these separate functions to exchange values of all these different types, we write a single template swap() function like this:
template<typename T> void swap(T& first, T& second) { T temp = first; first = second; second = temp; }
This template function is a "blueprint" for each of the above overloaded functions and many more besides. Note how the generic type T is used in the same way that any specific type such as int or string would be used.
Once such a template function has been defined, to make use of it we have only to do the following. If, somewhere in our code, we need to exchange two integer values, say i and j, we have only to make the following function call
swap(i, j);
and a version of the swap function capable of swapping the value of two integer values will be created and used in the given context.
First of all, a template class has the (typical, though simplified) general structure shown in
//NameOfClass.h #ifndef NAMEOFCLASS_H #define NAMEOFCLASS_H template<typename T> class NameOfClass { public: NameOfClass(); NameOfClass ( parameter_list ); void doIt ( parameter_list ); T getValue(); ... private: T value; } #endif
in which the keyword typename may be replaced by class, but the more "up-to-date", and recommended, choice is typename.
The class specification shown above would be implemented like this:
//NameOfClass.cpp #ifndef NAMEOFCLASS_CPP #define NAMEOFCLASS_CPP template<typename T> NameOfClass<T>::NameOfClass() { ... } template<typename T> NameOfClass<T>::NameOfClass ( parameter_list_with_several_parameters ) { ... } template<typename T> void NameOfClass<T>::doIt ( parameter_list ) { ... } template<typename T> T NameOfClass<T>::getValue() { ... } ...
When using a template class, it is important to remember that most C++ compilers do not permit the separate compilation of template classes.
One alternative is to place all of the class code (both specification and implementation) in a single include-file. When this is done (for any class, not just a template class) the file is often (by convention) given an extension of .hpp to distinguish it from both a .h file and a .cpp file.
Another alternative is to keep the specification and implementation in separate files, with .h and .cpp extensions as usual, but include both the .h and the .cpp file, one immediately after the other, in that order.