Templates: Generic Programming
Writing one function or class that works across multiple types, without duplicating code.
What you'll learn
- Write a function template parameterized over a type T
- Explain that the compiler generates a separate concrete function for each type a template is used with
- Predict a templated function's return type based on the argument types it's called with
Explanation
A template lets you write one function (or class) that works across multiple types, without writing a separate copy for each one. template <typename T> T maxValue(T a, T b) { return (a > b) ? a : b; } declares maxValue generically over a placeholder type T -- T stands in for whatever real type is used at each call site.
Calling maxValue(3, 7) with two ints makes the compiler deduce T = int from the arguments and generate a real, concrete int maxValue(int, int) function specifically for that call. Calling maxValue(2.5, 1.5) with two doubles separately makes the compiler generate an entirely different concrete double maxValue(double, double) function. This process -- generating a distinct real function per type actually used -- is called template instantiation, and it happens automatically at compile time; you never see or write the generated versions yourself.
This is genuinely different from function overloading (this course's earlier control-flow lesson): overloading requires you to write each version by hand, while a template requires writing the logic only once, with the compiler doing the repetitive work of generating a version per type. The tradeoff is that template code can only use operations that are genuinely valid for whatever type T ends up being -- maxValue's a > b comparison requires T to support >, so maxValue would fail to compile for a type that doesn't define that operator.
Guided lab
Predict: A template instantiated for two different types
Read this program and predict exactly what it prints.
#include <iostream>
template <typename T>
T maxValue(T a, T b) {
return (a > b) ? a : b;
}
int main() {
std::cout << "Max int: " << maxValue(3, 7) << std::endl;
std::cout << "Max double: " << maxValue(2.5, 1.5) << std::endl;
return 0;
}Stuck? Get a hint.
Common mistakes
- Writing the same function multiple times, once per type, instead of writing one template the compiler can instantiate for each type actually used.
- Confusing templates with function overloading -- overloading requires a hand-written version per type; a template requires the logic written once, generated per type by the compiler.
- Using an operation inside a template that isn't valid for every type it might be instantiated with, causing a compile error only for those specific types.
Knowledge check
Takeaway
Write generic logic once with `template <typename T>`, and let the compiler instantiate a concrete version for each type actually used at a call site.
Summary
Templates let one function or class body work across multiple types; the compiler generates a distinct concrete version per type actually used, a process called instantiation.
References
Your notes
Notes save automatically.
Finished this lesson?
Mark it complete to track your progress and schedule a future review.
AI tutor
The optional AI tutor isn't enabled in this deployment. All lessons, exercises, quizzes, and search work fully without it.