C++: Templates
Write code once and let the compiler generate it for any type, learn function templates, class templates, specialization, multiple parameters, and default arguments.
What are Templates?
A template is a blueprint that tells the compiler how to generate code for a family of types. Instead of writing a separate max() for int, another for double, and another for string, you write one template and the compiler produces all three automatically when you use them. The entire STL ( vector, map, sort ) is built on templates.
Templates: Write Once, Use for Any Type
Template code is not compiled until it is used. The compiler stamps out a new concrete version (an instantiation) each time you use the template with a distinct type.
- No runtime overhead: all type substitution happens at compile time
- Type-safe: each instantiation is checked independently by the compiler
- Two kinds: function templates and class templates
- Template definitions must be visible at the point of use, typically placed in header files
Function Templates
A function template begins with template<typename T> followed by a normal function definition. Everywhere T appears in the function, the compiler substitutes the actual type when you call it. You can let the compiler deduce T from the arguments, or specify it explicitly with getMax<int>(a, b).
Function Template
The compiler deduces T automatically from the argument types in most cases. Explicit syntax: functionName<Type>(args).
- Syntax: template<typename T> T functionName(T a, T b) { ... }
- class and typename are interchangeable as the keyword before T
- The compiler creates a separate concrete function for each distinct T used
- If deduction is ambiguous, provide the type explicitly: getMax<double>(3, 4.5)
Generic getMax() Function Template
C++One template, three instantiations. The compiler generates separate int, double, and char versions.
Generic swap()
A swap function is another classic template use case. The template parameter T works for any type that supports assignment. The standard library already provides std::swap in <utility>, writing your own demonstrates how it works.
Template with References
Pass by reference (T&) so the function modifies the original variables, not copies. The template T is still deduced from the argument types.
- Parameters are T&, references to allow actual swapping
- Works for int, double, string, or any assignable user-defined type
- The temporary variable temp is also of type T
- std::swap in <utility> is the production version of this exact pattern
Generic swap() Template
C++The same template body swaps ints and strings. T& ensures the originals are modified.
Class Templates
A class template defines a class where one or more types are left as parameters. When you instantiate it with a concrete type, the compiler generates the full class. Member functions defined outside the class body must also carry the template<typename T> prefix.
Class Template
Syntax: template<typename T> class ClassName { ... }; Instantiate with: ClassName<int> obj;
- Declare: template<typename T> class Box { T value; ... };
- Instantiate: Box<int> b(42); or Box<string> s("hi");
- Member functions defined outside the class: template<typename T> void Box<T>::setValue(T v) { ... }
- Each instantiation is a completely separate class with its own member functions
Box Class Template
C++One class definition, three distinct instantiations. Each Box holds and manages its own type.
Multiple Template Parameters
A template can have more than one type parameter. The Pair class below stores two values of potentially different types, mirroring how std::pair works in the STL. Each parameter is listed separately in the template parameter list.
Multiple Type Parameters
Syntax: template<typename T, typename U>. T and U are independent, they can be the same type or different types at the call site.
- template<typename T, typename U> class Pair { T first; U second; ... };
- Instantiate: Pair<string, int> p("Alice", 90);
- Both T and U can be deduced for function templates when both appear in the parameter list
- std::pair and std::map use exactly this pattern internally
Pair Class with Two Template Parameters
C++T and U are independent. Pair<string,int> and Pair<int,int> are two distinct instantiated classes.
Template Specialization
Template specialization lets you provide a custom implementation for a specific type while keeping the generic version for everything else. When the compiler sees a call with the specialized type, it uses your custom version instead of the generic one.
Full Specialization
Specialization syntax: template<> ReturnType functionName<SpecificType>(params). The empty template<> signals this is a full specialization, not a new template.
- The generic template handles all types by default
- A specialization overrides the generic version for one specific type
- Full specialization: template<> void print<string>(string s) { ... }
- Partial specialization is also possible for class templates: template<typename T> class Box<T*> { ... }
Template Specialization for string
C++The string version gets its own implementation. All other types use the generic template.
Default Template Arguments
Template parameters can have default types or values, just like function parameters can have default values. If the caller does not supply a type argument, the default is used. This is how std::vector<int> works, it has a second template parameter for the allocator that defaults to std::allocator<T> and is almost never written explicitly.
Default Template Arguments
Syntax: template<typename T, typename U = int>. If the caller writes Pair<string>, U defaults to int.
- Default type: template<typename T = int> class Box { ... };
- Default value: template<typename T, int SIZE = 10> class Array { ... };
- Defaults must appear at the end of the parameter list (right to left)
- All STL containers have default allocator and comparator template arguments that you rarely need to specify
Default Template Argument
C++Pair<string> uses the default U = int. Pair<string, double> overrides it explicitly.
Generic Stack Class Template
Combining a class template with a non-type template parameter (an integer for capacity) produces a fully generic, fixed-size stack that works for any element type. This mirrors how std::stack is structured internally.
Non-type Template Parameter
Template parameters can be values (like int SIZE), not just types. The compiler treats SIZE as a compile-time constant, so it can be used to declare an array inside the class.
- template<typename T, int SIZE = 10> class Stack { T data[SIZE]; ... };
- SIZE is a compile-time constant, legal as an array size inside the class
- Stack<int> uses default SIZE = 10; Stack<double, 5> uses SIZE = 5
- Different instantiations (Stack<int,10> vs Stack<int,5>) are separate types
Generic Stack with Non-type Parameter
C++T sets the element type; SIZE sets the capacity at compile time. Stack<int> and Stack<double,5> are independent types.
Templates in the STL
Every container and algorithm in the STL is a template. vector<int> is an instantiation of the vector class template with T = int. std::sort is a function template that accepts any iterator range and any comparator. Understanding templates explains why the STL works so uniformly across all types.
STL is Built on Templates
Every time you write vector<string> or map<string, int>, you are instantiating a template. The same sort() works on vector<int>, vector<string>, and a plain array.
- vector<T>: class template, stores a dynamic array of T
- map<K, V>: class template with two parameters, keys of type K, values of type V
- sort(first, last, comp): function template, works on any random-access iterator range
- Writing your own generic Stack or Pair is exactly what the STL authors did at a larger scale
Template Function with STL Containers
C++printAll is a single template that works with vector<int> and vector<string>, no overloads needed.
Knowledge Check
1. What is the purpose of a function template?
2. What keyword introduces a template parameter?
3. When does the compiler generate the actual code for a template?
4. What is template specialization?
5. Which syntax declares a class template named Box holding one type parameter T?
6. How do you instantiate a class template Box with type double?
7. Can a template have more than one type parameter?
8. What is a default template argument?