Templates in C++
A template lets you write a function or class once and use it with any type. Instead of writing maxInt, maxDouble, and maxString, you write one max template and the compiler generates the right version for each type you call it with. Templates are how the C++ Standard Library provides std::vector, std::map, and the rest — one definition, infinite element types. This is called generic programming.
Here is the smallest useful template.
A function template
The template <typename T> line introduces a placeholder type T that the compiler fills in per call.
#include <iostream>
#include <string>
// works for any type that supports >
template <typename T>
T largest(const T& a, const T& b) {
return (a > b) ? a : b;
}
int main() {
std::cout << largest(3, 7) << "\n"; // T = int -> 7
std::cout << largest(2.5, 1.1) << "\n"; // T = double -> 2.5
std::cout << largest<std::string>("ab", "cd") << "\n"; // T = string -> cd
}
The compiler reads largest(3, 7), deduces T = int, and stamps out an int version. This stamping-out is called template instantiation. You usually do not state the type — the compiler deduces it from the arguments.
A class template
Class templates generalise the type they store or operate on. Here is a tiny generic pair-like box.
#include <iostream>
#include <string>
template <typename T>
class Box {
T value; // stores any type T
public:
explicit Box(T v) : value(std::move(v)) {}
const T& get() const { return value; }
};
int main() {
Box<int> a{42};
Box<std::string> b{"hello"}; // a different instantiation
std::cout << a.get() << " " << b.get() << "\n"; // 42 hello
}
Box<int> and Box<std::string> are two distinct classes generated from one template. For class templates you typically write the type explicitly in angle brackets (though C++17 can often deduce it too).
Want to learn this properly?
Join the waitlist for our courses — beginner-friendly, project-first classes in Jalgaon.
Browse coursesMultiple type parameters
Templates can take more than one type, just like std::map<Key, Value>.
template <typename A, typename B>
struct Pair {
A first;
B second;
};
Pair<std::string, int> score{"Asha", 95};
What templates require of a type
A template silently assumes the type supports whatever operations the body uses. largest uses >, so it works for any type with a > operator and fails to compile for types without one. The error appears only when you instantiate the template with an unsuitable type — one reason template errors can look long. C++20 concepts let you state these requirements up front for clearer messages:
#include <concepts>
// only accept types that can be compared with >
template <typename T>
requires std::totally_ordered<T>
T largest(const T& a, const T& b) {
return (a > b) ? a : b;
}
Now calling largest with a type that cannot be ordered produces a short, readable error ("constraint not satisfied") instead of a wall of template-instantiation noise. Concepts make generic code both safer and self-documenting.
Common mistakes
- Splitting template definitions across .cpp files. Templates are usually fully defined in headers, because the compiler needs the full definition at every instantiation point. Splitting the body into a separate .cpp file commonly causes "undefined reference" link errors.
- Assuming a type supports an operation it does not.
largeston a type without>fails at instantiation, not at the template's definition. - Forgetting the angle brackets for class templates. Write
Box<int>, not justBox, when naming the type. - Over-templatising. If a function will only ever take an
int, a template adds complexity for no benefit. Use templates where genuine type-generality pays off.
FAQ
What is the difference between a function template and a class template?
A function template generates functions for different types (the compiler usually deduces the type from arguments). A class template generates whole classes for different types, and you usually name the type explicitly, as in std::vector<int>.
Are templates slower than normal code? No. Templates are resolved at compile time and produce ordinary, fully optimised code for each type — there is no run-time cost like a virtual call.
Keep learning
- Templates power the containers covered in The C++ STL Explained.
- See a heavily-templated container in Vectors in C++.
- Browse the full series on the C++ OOP hub.
Go from basics to generic programming with mentors in Jalgaon — join the waitlist for our C++ Programming course.
Want to learn this properly?
Join the waitlist for our courses — beginner-friendly, project-first classes in Jalgaon.
Browse coursesFounder, Infoplanet
Atul Kabra founded Infoplanet in 2001 and has spent over two decades teaching programming — C, C++, Java, databases and more — to students across Maharashtra.
Related guides
Classes & Objects in C++
Understand C++ classes and objects — defining a class, creating objects, member functions, and access control with public and private members.
Constructors & Destructors in C++
Understand C++ constructors and destructors — how objects are initialised and cleaned up, including parameterised, copy constructors, and initializer lists.
Encapsulation & Abstraction in C++
Understand encapsulation and abstraction in C++ — hiding internal data, exposing controlled interfaces, and why both make code safer and easier to change.
