Templates¶
Templates allow you to write generic code that works with any data type. They are the foundation of the STL.
Function Templates¶
Instead of writing multiple functions for int, double, etc., write one template.
Template Argument Deduction¶
The compiler usually deduces T automatically. You can also specify it explicitly:
Class Templates¶
Useful for container classes.
Template Specialization¶
You can provide a specific implementation for a particular type.
Full Specialization¶
Use this when you want completely different behavior for a specific type.
Partial Specialization¶
You can specialize a template for a subset of types (e.g., all pointer types), while keeping some template parameters generic. Note that function templates cannot be partially specialized (use overloading instead); this mostly applies to class templates.
Non-Type Template Parameters¶
Templates can take values, not just types.
Variadic Templates (C++11)¶
Templates that accept an arbitrary number of arguments. In C++11, this is typically handled via recursion:
- Base case: Handle the last element (or empty state).
- Recursive step: Process one argument and call the function again with the rest.
Fold Expressions (C++17)¶
C++17 introduced fold expressions, which dramatically simplify variadic templates by removing the need for recursion.
Concepts (C++20)¶
Concepts allow you to constrain template parameters, making error messages readable and interfaces clearer. Instead of just typename T, you specify what kind of T is allowed.
Deducing This (C++23)¶
C++23 introduces "Explicit Object Parameter", often called "Deducing This". It allows the member function to deduce the type of this (the object it's called on), which helps with CRTP-like patterns and recursive lambdas.
Common Pitfalls: Templates and Header Files¶
A very common mistake is defining template functions in a .cpp file.
Rule: Template definitions must usually be in the header file (.h / .hpp).
Why?¶
Templates are not code; they are "blueprints". The compiler generates the actual code (instantiation) only when the template is used. If the definition is in a .cpp file, compiling main.cpp won't be able to see the blueprint to generate the code, leading to "undefined reference" linker errors.
Incorrect:
math.h: template<typename T> T add(T a, T b);
math.cpp: template<typename T> T add(T a, T b) { return a + b; }
Correct:
math.h: Put the implementation here!