Introduction
Without templates you would write maxInt, maxDouble and maxString, all the same except for the type. A template is code with a type parameter, T, that the compiler fills in for each type you use.
Writing the same function three times for three types is tedious and error-prone. Templates let you write it once and let the compiler produce each version, which is exactly how the standard library's containers are built.
How it works
Function templates
#include <iostream>
#include <string>
using namespace std;
template <typename T>
T largest(T a, T b) {
if (a < b) return b;
return a;
}
int main() {
cout << largest(3, 9) << endl;
cout << largest(2.5, 1.5) << endl;
string a = "apple", b = "banana";
cout << largest(a, b) << endl;
return 0;
}template <typename T> introduces the type parameter. When you call largest(3, 9), the compiler sees two ints, deduces T = int, and writes largest<int> for you. largest(2.5, 1.5) gets a separate largest<double>, and largest(a, b) with strings a largest<string>. Look at the frame names in the call stack: each type has its own version.
The template works for any type that supports what it uses: here <. largest(3, 2.5) fails, because T cannot be both int and double.
Syntax
template <typename T>
T largest(T a, T b) { return a < b ? b : a; }
template <typename T>
class Box {
T value;
public:
Box(T v) : value(v) {}
};
Box<int> b(3);
Example
#include <iostream>
#include <string>
using namespace std;
template <typename T>
class Stack {
T items[10];
int count;
public:
Stack() : count(0) {}
void push(T x) {
items[count++] = x;
}
T pop() {
return items[--count];
}
bool empty() const {
return count == 0;
}
};
int main() {
Stack<int> numbers;
numbers.push(1);
numbers.push(2);
cout << numbers.pop() << numbers.pop() << endl;
Stack<string> words;
words.push("first");
words.push("second");
while (!words.empty()) cout << words.pop() << " ";
cout << endl;
return 0;
}Stack<T> is a stack of any type. Stack<int> and Stack<string> are two different classes made from the same code; you name the type in the angle brackets. This is exactly how vector<int> and vector<string> work in the standard library (next lesson).
Line by line
template <typename T>makesStacka class template, withTstanding for the item type.- The stack keeps up to 10 items of type
Tin an array, withcountsaying how many are in use. pushstores an item at indexcountand then adds 1.popsubtracts 1 and returns that item.Stack<int> numbersis a stack of ints. Pushing 1 and 2 and popping twice prints21, because the last item in comes out first.Stack<string> wordsis a separate class made from the same template. Its loop printssecond first.
Expected result
21
second first
In the real world
vector, map, sort and max in the standard library are all templates, which is why they work with your own types. Templates also let libraries such as Eigen do maths on matrices with no run-time cost for the generality.
Common mistakes
- Mixing types that the template forces to be equal:
largest(3, 2.5). Writelargest<double>(3, 2.5), or make both arguments the same type. - Using a template with a type that lacks an operation it needs (
<for a class withoutoperator<): the error points into the template. - Putting a template's code in a .cpp file and only declaring it in a header: other files then cannot make their own versions.
Best practices
- Start from a working version for one type, and then turn it into a template.
- Pass template parameters by
const T&when T may be large. - Document which operations a template needs from its type.
Summary
A template is code with a type parameter, and the compiler makes a version for each type that is used. Function templates deduce T from the arguments, and class templates name it in angle brackets, such as Stack<int>.
Quick check
Key takeaways
- One template can produce code for many types.
- Each type used gets its own version, made at compile time.
- A type works with a template only if it supports every operation the template uses.
Practice problems for this lesson
My notes
Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.