Using Template Classes

Introduction

Template classes are also known as parametrised types. The problem they solve is this: suppose someone wants to author an array class (for example). The obvious question is this -- an array of what ? Ideally, it should be possible to write a class that can behave as an array of anything, so that it is not necessary to write a new array class for every possible data type, especially since the behaviour of an array really does not depend on the data type stored in it.

C++ solves this problem by using templates. Templates allow the user to specify the class type. In this document, we specify how one uses template classes.

Using a Template Class

Template classes take several parameters. The parameters are usually class names, and for the examples that we will consider, that is what is used.

While most template classes in the standard library take several arguments, templates use default arguments which behave the same way as default arguments in C++, so it is usually only necessary to specify one template argument. Template arguments are specified using the following notation:

std::vector<int> v;	// a vector of int
std::vector<std::string>; // a vector of string
std::vector<vector<int> > w; // a vector of vectors of int

Template Declarations

You will not need to use template declarations until you start designing container classes. However, it's likely that you'll see them (for example, in this article), so it helps to understand how they work. If a function or class declaration is preceded by the following:

template <class T>
it means that the symbol T is used to denote a type that will be supplied later by the user. This gives library writers the flexibility to write classes that support any type that supports an appropriate set of operations (usually, default constructors, copy constructors, assignment operators, and comparison operators are required)

Using Template Functions

Many functions in the standard library also use templates. Fortunately, the C++ standard allows functions to deduce template parameters from the function arguments. For example, given this example:

template<class T> void foo(T){}
double x;
foo(x);
the compiler can deduce that the required function is foo<double>().

By using template functions, the standard library is able to provide very general functions that not only work for standard library classes, they work for ordinary data types, and user defined classes. For example, the following code:

random_shuffle ( start, end );
	
can be used to shuffle C-style arrays ( start and end are pointers ), or vectors (where start and end are iterators). The only requirement this function has is that the container has random access and array-like semantics.