C++ Templates

C++ templates are a powerful mechanism for code reuse, as they enable the programmer to write code that behaves the same for data of any type. So we can view templates as molds which can create many shapes of similar types with any type of material filled into them.

Templates are also known as generic functions or classes which are used to implement a generic structure for many structures of the same statements with different data-types.

Templates are expanded by the compiler in as many definitions as the function calls of the different types used.

We can declare a template with the keyword template. Like so:


	template<typename T>
	template<class T>

The template keyword tells the compiler that what follows is a template, and that T is a template parameter that identifies a type.

Note: The name T is often used, but we could give it any name we want. We could call it my_T for example.

As we did with regular function parameters, we also can use template parameters to pass types to a function or class. The function or class templates in turn can use these parameters as if they were any other regular type.

There are two types of templates:

  • Function templates
  • Class templates

Function templates are declared in the following way:


	template <class identifier> function_declaration;
	template <typename identifier> function_declaration;

Class templates are declared in the following way:


	template <class identifier> class_declaration;
	template <typename identifier> class_declaration;

As you can see we can use the keyword class or the keyword typename. Its use is indistinct, since both expressions have exactly the same meaning and behave exactly the same way.

Function templates

As we said above to create a function template we say:


	template<typename T>
	void my_function()
	{
		.......
	}

Now let’s take a look at an example that you actually can compile:


	#include<iostream>
	#include<string>
	using namespace std;

	template<typename T>
	void print_mydata(T output)
	{
		cout << "Output value: " << output << endl;
	}

	int main()
	{
		int i=5;
		double d=5.5;
		string s("Hello World");
		bool b=true;

		print_mydata(i); // T is int
		print_mydata(d); // T is double
		print_mydata(s); // T is string
		print_mydata(b); // T is bool
		return 0;
	}

As we said before, templates are expanded by the compiler in as many definitions as the function calls of the different types used. Data-types are represented by a common name, which is replaced by different actual data-type by the compiler, during compilation. Data-types used by the compiler, are evaluated using the function calls made by the programmer in the program.

In the example above, the compiler will create four definitions of the print_mydata function as follows (as per the function call):


	void print_mydata(int output)
	{
		cout << "The value is: " << output << endl;
	}

	void print_mydata(double output)
	{
		cout << "The value is: " << output << endl;
	}

	void print_mydata(string output)
	{
		cout << "The value is: " << output << endl;
	}

	void print_mydata(bool output)
	{
		cout << "The value is: " << output << endl;
	}

Note: As you can see, only the type of the parameter output is changing.

For function templates, there are two options to specify the template parameters.


	template<typename T>
	void my_function()
	{}

	int main()
	{
		my_function<int>(2);
		my_function<double>(2.1);
	}

Or we could do this (like we did in the first example print_mydata):


	template<typename T>
	void my_function(T value)
	{}

	int main()
	{
		//T = int
		my_function(2);
		//T = double
		my_function(2.1);
	}

The following points you could also do with template functions:

  1. One template function can use more than one generic type. We could say: template(typename T, typename T1)
  2. We can use specific data-types along with the generic types in the function templates.

So for example:


	template<typename T>
	void print_mydata(T output, int a)

So if we call print_mydata from main it should be something like this:


	int i=5;
	double d=5.5;
	print_mydata(i, 5);
	print_mydata(d, 5);

Note: The second parameter should always be an integer.

3)We can overload the function templates (by creating another overloaded template function of the same name).

Function templates have the following advantages:

  • Function overloading can be easily implemented.
  • A function is expanded by the compiler when needed, so unnecessary burden of computer power during execution, is reduced.
  • Codes written are in generic mode, so any changes made will be reflected in each definition automatically.

Class templates

Class templates are associated with the generic types and they can use some specific types as well. But all objects must be of some specific size, so before creating an object of the template class, the data-type must be specified. This is done by specifying the data-type as parameter when the object is created for the template class.

Template classes are a great help for creating applications with generic types, which are common applications such as linked list, stack, and queues etc.

Let’s take a look at an example (in this case a simple stack example):


	#include <iostream>
	#include <string>
	using namespace std;

	template <class T>
	class Stack
	{
	public:
		Stack();
		void push(T i);
		T pop();
	private:
		int top;
	T st[100];
	};

	template <class T>
	Stack<T>::Stack()
	{
		top = -1;
	}

	template <class T>
	void Stack<T>::push(T i)
	{
		st[++top] = i;
	}

	template <class T>
	T Stack<T>::pop()
	{
		return st[top--];
	}

	int main ()
	{
		Stack<int> int_stack;
		Stack<string> str_stack;
		int_stack.push(10);
		str_stack.push("Hello");
		str_stack.push("World");
		cout << int_stack.pop() << endl;
		cout << str_stack.pop() << endl;
		cout << str_stack.pop() << endl;
		return 0;
	}

Note: A stack uses the “first in, last out” principle. So in this case the string Hello was first in (then the string World), so the string World comes out first and than the string Hello comes out!

Note2: In normal circumstances there is never an implementation file (*.cpp) for a template class. All member functions should be declared in the header file (*.h). (Then in main.cpp file this header file is included).

The example speaks for itself but we lift one thing out:


	template 
	T Stack::pop()

Are you confused by so many T’s? There are three T’s in this declaration: The first one is the template parameter. The second T refers to the type returned by the function. And the third T (the one between angle brackets) is also a requirement: It specifies that this function’s template parameter is also the class template parameter.

That is all for this tutorial!

This entry was posted in C++ Tutorials. You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed. Tweet This! Tweet This! or use to share this post with others.

There is currently one response to “C++ Templates”

Why not let us know what you think by adding your own comment!

  1. p on January 29th, 2011:

    struct Foo {
    template
    struct Member {
    typedef int type;
    };
    };

    template
    struct Bar {
    typedef typename T::template Member::type bar;
    };

    typedef Bar FooBar;