Templates is an important part of the C++ language. Templates is a language within the language. There are two kinds of templates, one is function templates and the other is template classes. This chapter will only go through the basic usage and explanations.
A fun fact about templates, is that C++ templates are Turing complete. If something is Turing complete, it can be used to compute any problem solved by computation.
In other languages like Java and C# templates
are called generics
. In C++ those are called templates
and templates are the second most important feature in C++ (with destructors being the most important feature).
The concept of generic programming is to write code once, and this code will be valid for all intended types. For basic methods, a beginner will think it’s OK to write overloads for all types, for the same algorithm. But that’s really the hard way (and not very smart) of doing things.
It was possible to write generic code before templates in C and pre-template C++, but that was not type-safe. A generic sort method could only accept void* parameters, and it had to know the size of each element, how many elements to sort over and a predicate. Every interface had to be void* because there were no language feature to ensure type safety. If you sorted ints, the predicate must be int
. If you sorted longs, the predicate must be long
.
Due to legacy reasons, those interfaces using void*
are available, but new code shouldn’t use those at all.
Here is a prime example on how the situation was before templates came along (and still is in C).
// Please do not use this code. It's very inefficient and error prone.
#include <stdlib.h>
#include <search.h>
// Predicate
int compare_ints(const void * a, const void * b)
{
// Cast to int* from void*, then deference to int
int val1 = *((int*)a);
int val2 = *((int*)b);
// Predicate should return 0 if identical
if (val1 == val2)
return 0;
// -1 for less than, 1 for greater than
return (val1 < val2) ? -1 : 1;
}
void sort_ints()
{
#define NUM_INTS 10
int arr[NUM_INTS];
// Create a reverse list of ints from 10 to 1
for (int i = 0; i < NUM_INTS; ++i)
{
arr[i] = NUM_INTS - i;
}
// Sort
qsort(&arr, NUM_INTS, sizeof(int), &compare_ints);
}
Please do not use qsort
in any new code, and do replace any occurrence of qsort
with std::sort
. And do only replace those occurrences you’re able to test. The interface is not identical between qsort
and std::sort
, so there may be corner cases where the actual order is not identical (with identical keys).
Here’s how to solve this particular example with class templates.
Tutorial about C++ Function Templates with examples.
Here’s a good C++ Class Templates Tutorial with simple and complex examples.
Specialized class templates description and examples.
Professional Software Developer, doing mostly C++. Connect with Kent on Twitter.