Templates

Chapter 7 Weiss

Chapter 14 Lafore

 

Quote from Stroustrup

•      “You are strongly encouraged not to be distracted or discouraged by an incomplete understanding of details”

•      The purpose of this course is to get you started on the C++; it is not possible to teach everything about it.

 

Function templates

•      Used when the you want to perform the same operation on different data types.

•      The definition of HOW to perform the operation must be the same for different data types

•      Two new keywords

–  template

–  typename

 

•      Suppose you want to swap two integers
void swap(int &x, int &y)
{ int temp
   temp = x; x = y; y = temp;}

•      Now suppose you want to swap two characters
void swap(char &x, char &y)
{char temp
   temp = x; x = y; y = temp;}

•      A template to swap any two items; the type is generic

  template <typename T>
 void swap(T &x, T &y)
 {T temp
   temp = x; x = y; y = temp;}

 

Example: finding a maximum

int max (int v1, int v2, int v3)

{ int big = v1;

   if (v2 > big) big = v2;

    if (v3 > big) big = v3;

    return big;}

 

template <typename T >

T max (T v1, T v2, T v3)

{T big = v1;  //declare a local variable

   if (v2 > big) big = v2;

    if (v3 > big) big = v3;

    return big;}

 

Instantiating the template function

•      The template itself has no type associated with it.

•      You must tell the compiler what type you want substituted for the T

–   i.e. you must make an instance of the template with a real data type

•      You instantiate the template function by when you call it with actual data types

 

Calling a template function

•      The call:  w = max(x,y,z);

•      If w, x, y, z have been declared as integers, the compiler will make a function where int replaces the T

•      Another call: a = max(b,c,d);

•      If you call again with a, b, c, d which have been declared as floats, the compiler will make another copy, this time substituting float for T

 

Prototypes

•      You can have a template function prototype
template <typename T>
T max (T v1, T v2, T v3);

•      This is often on a single line; white space makes no difference to the compiler

•      Usually the names for the variables are ommitted in prototypes

•   template <typename T>
T max (T, T, T);

 

A word on terminology

•      template is a keyword and must be used

•      T is user-defined, and could be anything, like replaceIt, or myType

•      typename is a keyword, but is often used interchangeably with the keyword class

•      These are equivalent:
  
template <typename T>
 template <class myType>

 

Types for function templates

•      The generic type (called the template argument) can be either a built-in type or it can be a user-defined type

•      The generic type can be used in three places:

–   to specify the types of the arguments to the function,

–   to specify the return type of the function, and

–   to declare local variables within the body of the function definition.

 

Templates are a way to generate code

•      A copy of the function is generated by the compiler for every type for which the function is called

•      So the compiler is actually generating code for you.

•      Note that is not explicitly necessary to tell the compiler the value for T

–   It can deduce the type from the call

 

Templates, the compiler and linker

•      A function template does not do anything by itself, it is only a blueprint the compiler uses to create functions from function calls.

•      The compiler uses a template to generate source code for a function definition, which it then compiles.

•      The role of the linker is to link a single instance of a function into the executable module, even if it is called several times.

•      When the program executes, the existence  of a template in the original source code is neither apparent nor relevant.

 

Templates and overloading

•      When do you use a template, and when do you overload?

•      Templates and overloading have different purposes

–   If the definition is the same for different data types, you use a template

–   If you want to perform similar operations that involve different program logic on different data types you overload

 

For C programmers

•      Macros perform much the same functionality as templates

•      Macros are NOT used much in C++ because:

–   They do not perform any type checking

–   This may lead to errors that are very hard to find.

•      Moral:  use templates instead of macros!

 

Class templates

•      Generally used for data storage (container) classes

•      If you declare a stack or linked list to work with one type of data, it only works with that one type

•      Class templates allow the type to be generic

   template<class T>

   class Stack  {….}

 

Instantiating the class

•      Classes are instantiated by defining an object using the template argument

•      EX  Stack<float> s1;
   Stack<long>  s2;

•      The compiler provides space in memory for the object’s data

•      It also provides space for the member functions if they have not already been placed there by another object of that type

 

Example of a stack class template

template <class Type>

class Stack

{ private:

     Type st[MAX];

     int top;

  public:

     Stack() {top = -1;}

     void push(Type var)

     {    st[++top] = var;}

     Type pop()

     {    return st[top--};}

};

 

Separate compilation of member functions

•      Compiler support for separate compilation of templates has been weak

•      So, in many cases, the entire class with its implementation is placed in a single header file

•      This is the way the Standard Template Library is often done.

If the member functions are defined externally

•      Syntax

template<class Type>

void Stack<Type>::push(Type var) {….}

•      Or  (when a constructor)

template<class Type>

Stack<Type>::Stack( ) {….}

 

Default template arguments

It is possible for template classes to have default arguments

The default  is specified in the template argument

template<class T,
    class container = vector<T> >

Instantiation

     MyClass<int> x1; 

            second parameter is a vector of type T