C++ Templates Demo


Templates in C++ are kind of advanced topic, some might see them as complex to understand or maybe because their use isn’t clear that causes confusion. I’m hoping this brief but straight to point overview on templates will give a guide on how, why, and where to use them.

In C++, suppose we have a method in a class called Add that takes two integers and returns am integer like so:

class Calc
{
    public:
          Calc(){}
          int Add(int a, int b){return a+b;}
}

Now…what if instead of adding integers, we wanted to add values that are of type double? That would mean rewriting already existing code and changing the int types to double in the implementation.

What we can do to work around this is create a template. Essentially all a template does is make the object or type you are working with, for example, a class that has functions that work with multiple types, generic. So a method, for instance, can not just only work with strings but also char types. To create a template for a class or method, simply write it above the declaration like so:

template <class T>
class Calc
{
    //declarations go here
}

In order to make full use of our template, we need methods and a class ctor like so:

//header files declared below
#include "targetver.h"

#include <stdio.h>
#include <tchar.h>

template <class T>
class Calc
{
public:
	Calc(){}
	T Add(T a, T b);
        T Subtract(T a, T b);
};

In the example above, you’ll notice that I only declared the methods and no implementation was done. This is because I’m using the header file to create my template along with declaring my class object.You can either use templates in the header file(s) or the main.cpp file or other .cpp files of your program. The methods in the Calc class declared are Add() and Subtract(). Both methods take two generic types and return a generic specified type. However, remember that we’ve only declared in the header, we haven’t implemented anything yet in our main.cpp file.

When I use this method in main.cpp, heres how it will look like (note the syntax used):

#include "stdafx.h"
#include <iostream>
#include "stdio.h"

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
        Calc<double> c;//type double specified between <>
	cout<<c.Subtract(10,5)<<endl;//testing the subtraction method
	system("pause");
	return 0;
}
template<class T>//we also need a template in the implementation to allow generic types to be allowed
T Calc<T>::Subtract(T a, T b)//note the syntax
{
	return a-b;
}

On the example above, we see that we also need a template for the method implementation, these are called function templates. Class templates implement a generic type for the class object and its parameters,and functional templates can have a broad range of types that can be specified for the particular function.

What are templates useful for and additional info on their use:

  • Implementing data structures of generic types like a Queue<T> that can take strings or other class objects
  • Promote reusing of source code and a form of polymorphism
  • You can also specify parameters for templates like so, for example, converting type A to type B: template<class A, class B>

Illustrations of templates and how they work

Here’s another code sample (from https://www.tutorialspoint.com/cplusplus/cpp_templates.htm)

#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <stdexcept>

using namespace std;

template <class T>
class Stack { 
   private: 
      vector<T> elems;     // elements 

   public: 
      void push(T const&);  // push element 
      void pop();               // pop element 
      T top() const;            // return top element 
      bool empty() const{       // return true if empty.
         return elems.empty(); 
      } 
}; 

template <class T>
void Stack<T>::push (T const& elem) { 
   // append copy of passed element 
   elems.push_back(elem);    
} 

template <class T>
void Stack<T>::pop () { 
   if (elems.empty()) { 
      throw out_of_range("Stack<>::pop(): empty stack"); 
   }
	
   // remove last element 
   elems.pop_back();         
} 

template <class T>
T Stack<T>::top () const { 
   if (elems.empty()) { 
      throw out_of_range("Stack<>::top(): empty stack"); 
   }
	
   // return copy of last element 
   return elems.back();      
} 

int main() { 
   try { 
      Stack<int>         intStack;  // stack of ints 
      Stack<string> stringStack;    // stack of strings 

      // manipulate int stack 
      intStack.push(7); 
      cout << intStack.top() <<endl; 

      // manipulate string stack 
      stringStack.push("hello"); 
      cout << stringStack.top() << std::endl; 
      stringStack.pop(); 
      stringStack.pop(); 
   }catch (exception const& ex) { 
      cerr << "Exception: " << ex.what() <<endl; 
      return -1;
   } 
} 
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s