Templates


Templates

oop



Learning Objectives:

  • Explain the advantages of using function and class templates.
  • Make good use of function and class templates.
  • Explain the different types of template parameter, and make good use of them when defining C++ templates.
  • Explain the relationship between C++ templates and the object-oriented concept of polymorphism.

Introduction to Templates

Templates are used when a number of functions or classes are almost identical, except that they utilise different data types. They are used to make code shorter and easier to understand. A signal template function or class can be written, which is then instantiated to use a number of different data types. There are two types of template: function templates and class templates.

Function Templates

Function templates allow us to define a single function that can be instantiated many times for different types. To introduce the concept of function templates, consider the ‘maximum’ example mentioned below.

max.h
1 template < class t >
2 t find_max ( t a , t b ) {
3   if ( a > b )
4     return a ;
5     else
6     return b ;
7 }

To start with the function signature t find_max ( t a , t b ) is preceded by the definition (template <class t>) of type template parameter t which tells the compiler that this is a templated function. The identifier type t is a type template parameter: in other word, t will be considered to be a data type in the function, but it is not specified yet.

The type t can be any type, but the only restriction is that the comparison operator > must be defined for the type, since this is used in the function body (as the > operator is only defined for all of the simple data types).

Now let’s examine the main() function that calls the find_max function:

main()
#include <iostream>
#include "max.h"
using namespace std;

int main () 
{
  // find maximum of two integers
  int x, y;
  x = 12;
  y = 11;
  cout << "Maximum of " << x << " and " << y
       << " is " << find_max(x, y) << endl;
   
  // find maximum of two chars
  char p, q;
  p = 'w';
  q = 'c';
  cout << "Maximum of " << p << " and " << q
       << " is " << find_max(p, q) << endl;
  return 0;
}

To make use of the templated function all we need is to #include the max.h file. Only the find_max implementation for int and char will be instantiated at compile time.

Class Templates

Class templates allow us to define a single templated class that can be instantiated for different data types. To illustrate this concept consider the following example which implements a class for representing pairs of numbers, including a member function that returns the maximum of the two numbers. C

pair.h
template <class p>
class Pair{
  public:
    Pair(p val1, p val2) {
      _values[0] = val1;
      _values[1] = val2;
    }
    p getMax();
  private:
    p _values[2];
};

Note that the syntax for specifying a class template is the same as for function templates, by just adding the line template <class p>, where p is the identifier

The function body for getMax() still needs to be defined, this can be done by adding the following code to the pair.h file after the class definition:

template <class p>
p Pair<p>::getMax()
{
  if (_values[0] > _values[1])
    return _values[0];
  else
    return _values[1];
}

Note that when a member function body is defined outside of the class definition, the scope operator :: has to be used to indicate that it is a member function rather than a normal function.

The slight difference to the normal syntax for member function definitions is that now we have to include the type template parameter inside angled brackets after the class name, i.e. Pair<p>. Similarly when instances of the class are declared, the type must be defined using angled brackets like so Pair<int> for integer data types. This is shown in an example main() function below.

1 # include <iostream >
2 # include "pair .h"
3 using namespace std ;
4
5 int main ()
6 {
7   // find maximum of two integers
8   int x , y ;
9   x = 12;
10  y = 11;
11  Pair <int> myPair1 (x , y );
12  cout << "Max of " << x << " and " << y << " is "
13       << myPair1 . getMax () << endl ;
14
15  // find maximum of two chars
16  char p , q ;
17  p = ’w’;
18  q = ’c’;
19  Pair <char> myPair2 (p , q );
20  cout << "Max of " << p << " and " << q << " is "
21       << myPair2 . getMax () << endl ;
22
23  return 0;
24 }

Let’s consider another example of class templates, an array class. The motivation for defining a new array class is that arrays in C++ include no bounds checking, i.e. if the array index is out of rage then no error messages are display. A templated array class that the [] operator includes such bounds checking.

templated_array.h
template <class element, int n>
class TemplateArray {
  private:
    int _size;       // number of elements in array
    element *_array; // the elements
  public:
    // default constructor
    TemplateArray() {
      _size = n;
      _array = new element[_size];
    }
    // constructor that initialises all values to 'val'
    TemplateArray (element val)
    {
      _size = n;
      _array = new element[_size];
      for (int i = 0; i < _size; i++)
        _array[i] = val;
    }
    // overload the [] operator
    element& operator[] (int);
};

This class allows the programmer to instantiate new arrays using any data type, and also any length. Therefore, this time the class template defined in the templated_array.h file has two parameters, as indicated in the first line template <class element, int n>:

  • type template parameter element indicates the type of elements in the array.
  • value template parameter, an int parameter called n, which specifies the number of elements to be included in an array.

In fact any template definition (function or class) contains these two types of parameter

Templates and Polymorphism

The word polymorphism refers to a single object taking a number of different forms.

  • Virtual functions are an example of run time polymorphism.
  • Member function overloading is an example of static polymorphism.
  • Templates are another example of static polymorphism.

A templated function or class is a single entity in the program, but it can take on a number of different forms of data types. The different form for the function/class are instantiated at compile-time. s


return  link
Written by Toby Thomas & Tobias Whetton