Templates in C++

Template Definitions

We can define our own function and class templates to be instantiated and used with multiple different types, similar to the STL algorithms and classes.

Function Templates

Example:

template <class T>        // generic class type name T
T cubeit(T num)           // header using type T
{
    return num * num * num;   // assumes * operation defined for type T
}

int main(void) {
  cubeit(3);
}

Class Templates

For a simple type templated class declare as follows:

template <class T>
class MyTemplatedClass
{
	T mydata;
public:
	int myfun(int x);
	// ...
};

and declare member functions as follows:

template <class T>
int MyTemplatedClass<T>::myfun(int x) { ... }

In C++, the class definition and the function implementations must be in the same file! You can do this in either a .h, .cpp, or even .hpp file. That file must then be compiled with any other code using the templated class. Another approach is to put the template implementations in a separate file (*.inc) and then #include that at the end of your .h template header file.

Using multiple template parameters

  template <class T1, class T2>
  class C2 {
       public:
             C2() { };
             C2(T1 a, T2 b) { thing1=a; thing2=b; };
       private:
             T1  thing1;
             T2  thing2;
  };

  //usage
  C2<int, float>  a1;  // nothing is initialized
  C2<double, int> a2(2.3, 4);

Templates also support data parameters too, not just types.

    template <int Maxsize>  // Maxsize is int template parameter
    class Mstring {
            public:
                  Mstring() { str[0] = '\0'; }; 
            private:
                  char str[Maxsize];
    };

    // usage
    Mstring<20> name;  // copy of Mstring with 20 replacing Maxsize
    Mstring<10> city;  // copy of Mstring with 10 replacing Maxsize

    int i=5;
    //  Mstring<i> zip; // ILLEGAL - must use constant!!

    const int max=5;
    Mstring<max> zip; // LEGAL, max is const-declared

The example above is not a practical use of templates however. It wastes space because it makes a copy for each size. Also because they are different types technically, we can’t compare name and city variables to each other.