Templates

Templates allow C++ classes to be constructed to handle various types. A typical example is a stack class that can work with a variety of types so we don't need to copy the code.

A typical integer stack (with no error checking

class stack {
public:
   stack(){top=-1;};
   void push(int i) { s[++top]=i;};
   int pop() {return(s[top--]);};
private:
   int s[100];
   int top;
} // stack
A template stack

template <class SOME_TYPE>
class stack {
public:
   stack(){top=-1;};
   void push(SOME_TYPE i) { s[++top]=i;};
   int pop() {return(s[top--]);};
   SOME_TYPE top_of();
private:
   SOME_TYPE s[100];
   int top;
} // stack
To use this, we declare a stack of a given type:
   stack<char> char_stack;
   stack<int> int_stack;
To get the types right, if a member function is not defined inline, it looks like:
template<class SOME_TYPE> SOME_TYPE stack<SOME_TYPE>::top_of() { return(s[top];}
Inline, this would have been:
SOME_TYPE top_of() {return(s[top]);};

Templates Before and After

BeforeAfter
stack<int> stack<char> stack<node>
template <class SOME_TYPE>;
class stack {
public:
   stack(){top=-1;};
   void push(SOME_TYPE i) { s[++top]=i;};
   SOME_TYPE pop() {return(s[top--]);};
   SOME_TYPE top_of();
private:
   SOME_TYPE s[100];
   int top;
} // stack
  • function prototypes
    you can also make functions that take multiple types as arguments. Useful in generic methods. Example:
    template<class SOME_TYPE>
    void
    copy(SOME_TYPE a,SOME_TYPE b)
    {
       a=b;
    }//copy
    
    This can be done with multiple types as well.
    template<class SOME_TYPE1,class SOME_TYPE2>
    void
    copy(SOME_TYPE1 a,SOME_TYPE2 b)
    {
       a=b;
    }//copy
    
    This needs to make sense. If not, write an assignment operator so it does make sense. You may need to make special case versions. For example, the copy above won't work for arrays. You need to write a copy() that contains those types specifically, not generically. This will take precedence over template.
  • notes
    friend functions in a template class that don't take the template type as an arg, is a friend to all instantiations. Otherwise, it only applies to those instantiations that match its type signature.

    There are separate static members for each instantiation. This is expected. It would not mean anything if the static member was an int even when the template was a float.