Write It Once, Use It for Every Type
On the previous page you sorted a vector<int> with std::sort. But std::sort also sorts a vector<string>, a vector<double>, or an array of your own structs - without anyone writing a separate sort for each. That is not magic and it is not overloading. It is a template: a single piece of code the compiler reuses for whatever type you hand it.
Without templates you'd be stuck copy-pasting the same logic for every type. Here's the same maximum function written three times, which is exactly the duplication templates exist to kill:
int maximum(int a, int b) { return a > b ? a : b; }
double maximum(double a, double b) { return a > b ? a : b; }
string maximum(string a, string b) { return a > b ? a : b; }
The bodies are identical. Only the types differ. A template lets you say "this works for any type T" and write it once.
Function Templates
You turn a function into a template by adding template <typename T> in front of it and using T wherever a concrete type would normally go.
Notice you never wrote maximum<int> or maximum<double>. The compiler looks at the arguments and figures out what T should be - that's template argument deduction. Each distinct type you call it with causes the compiler to instantiate (generate) a separate concrete function behind the scenes.
You can spell out the type explicitly when deduction can't help, using angle brackets:
A common gotcha lurks in deduction. Because T must be a single type, mixing argument types breaks it:
maximum(3, 7.5); // ERROR: is T int or double? The compiler refuses to guess.
You can fix this by being explicit - maximum<double>(3, 7.5) - or by giving each parameter its own type parameter, which we'll do next.
Multiple Type Parameters
A template isn't limited to one type. List as many as you need, separated by commas. This is how you write a function whose parameters can be different types:
When the return type depends on the parameters, let the compiler work it out with auto (C++14 and later), which pairs naturally with templates:
Class Templates
Templates aren't just for functions - whole classes can be templated. This is exactly how the standard containers work: vector<int>, the key-value map, and pair<A, B> are all class templates. You write the data structure once and it stores whatever type you parameterize it with.
Here's a tiny generic Box that holds one value of any type:
The key difference from function templates: with a class template you usually have to supply the type in angle brackets - Box<int> - because there are no constructor arguments to deduce from in older standards. (C++17 added class template argument deduction, so Box b(42); works too, but being explicit is always safe and reads clearly.)
The Errors Will Be Enormous - Here's Why
This is the part that trips everyone up, so it's worth saying plainly. A template is only fully checked when it is instantiated with a real type. You can write a template that uses <, and it compiles fine on its own - the error only appears the moment you instantiate it with a type that has no <.
template <typename T>
T maximum(T a, T b) {
return a > b ? a : b; // requires that T supports >
}
struct Point { int x, y; };
// maximum(Point{1,2}, Point{3,4});
// ERROR: no operator > for Point. The message names Point AND
// quotes this whole function, often spanning many lines.
Because the compiler substitutes the full type into the template and reports failures from inside the generated code, a single mistake can produce a wall of output mentioning library internals. Two survival tips:
- Read the first error, not the last. Later errors are usually fallout from the first.
- Scan the message for your own type name (here,
Point). That tells you which instantiation went wrong.
The real fix is to make sure your type supports whatever the template needs - for maximum, that means overloading operator> for Point, which is a topic for a later page. Modern C++20 concepts can move these errors earlier and make them readable, but the substitution model underneath is the same.
Next: Classes
You just built a Box class template - a class with private data, a constructor, and member functions - while focusing on the templating. The next page slows down and teaches classes properly: how to bundle data with the functions that operate on it, what public and private really control, and how member functions access the object's own state. Templates and classes combine constantly in real C++, so a solid grip on classes makes generic code far easier to write.
Frequently Asked Questions
What is a template in C++?
A template is a blueprint that lets you write a function or class once and have the compiler generate a version for each type you use it with. You write template <typename T> and then use T as a stand-in for the real type. The compiler stamps out a concrete version - this is called instantiation.
What is the difference between typename and class in a C++ template?
typename and class in a C++ template?In a template parameter list, template <typename T> and template <class T> mean exactly the same thing. typename is generally preferred today because it reads more honestly - T can be any type, not just a class. The keyword choice has no effect on the generated code.
Why are C++ template error messages so long?
Templates are checked when they are instantiated with a real type, not when they are written. If a type doesn't support an operation you used (like < for sorting), the error appears deep inside library code with the full instantiated type spelled out, producing pages of output. Read the first error and look for your type name in it.