Lesson 17 • Advanced
Templates Deep Dive
Master type deduction, variadic templates, fold expressions, template specialization, and non-type parameters.
What You'll Learn
- ✓ Template argument deduction and if constexpr
- ✓ Variadic templates and parameter packs
- ✓ C++17 fold expressions
- ✓ Full and partial template specialization
Type Deduction & if constexpr
The compiler can deduce template arguments from the values you pass — you don't always need angle brackets. Combined with if constexpr, you can write branches that are evaluated at compile time, enabling different behaviour for different types without runtime cost.
template <typename T>
void process(T val) {
if constexpr (is_integral_v<T>) {
// Only compiled for integers
} else if constexpr (is_floating_point_v<T>) {
// Only compiled for floats
}
}Type Deduction & if constexpr
Let the compiler deduce types and branch at compile time
#include <iostream>
#include <vector>
#include <type_traits>
using namespace std;
// Template argument deduction — compiler figures out T
template <typename T>
void showType(T value) {
cout << "Value: " << value;
if constexpr (is_integral_v<T>) {
cout << " (integral type, size=" << sizeof(T) << ")";
} else if constexpr (is_floating_point_v<T>) {
cout << " (floating point, size=" << sizeof(T) << ")";
} else {
cout << " (other type)";
}
cout << endl
...Variadic Templates & Fold Expressions
Variadic templates accept any number of arguments using typename... Args. Before C++17, you'd recursively unpack them. With fold expressions, you can apply an operator to the entire pack in one line.
// Fold expressions (C++17)
(args + ...) // Unary right fold: a1 + (a2 + (a3 + a4))
(... + args) // Unary left fold: ((a1 + a2) + a3) + a4
(init + ... + args) // Binary left fold with initial valueVariadic Templates & Folds
Build functions that accept any number of arguments
#include <iostream>
#include <string>
using namespace std;
// Base case: no arguments
void print() {
cout << endl;
}
// Variadic template: process one arg, recurse on the rest
template <typename T, typename... Args>
void print(T first, Args... rest) {
cout << first;
if constexpr (sizeof...(rest) > 0) {
cout << ", ";
}
print(rest...); // Expand remaining args
}
// Fold expressions (C++17) — much cleaner!
template <typename... Args>
auto sum(Args... args) {
retu
...Template Specialization
Customise template behaviour for specific types
#include <iostream>
#include <cstring>
using namespace std;
// Primary template
template <typename T>
class Formatter {
public:
static string format(const T& value) {
return to_string(value);
}
};
// Full specialization for string
template <>
class Formatter<string> {
public:
static string format(const string& value) {
return "\"" + value + "\"";
}
};
// Full specialization for bool
template <>
class Formatter<bool> {
public:
static string format(const bool
...Common Mistakes
⚠️ Missing base case: Recursive variadic templates need a base case (empty parameter pack) or you'll get infinite compilation.
⚠️ Templates in .cpp files: Template implementations must be in headers — the compiler needs the full definition to instantiate.
⚠️ Confusing partial with full: Partial specialization works for class templates only, not function templates. Use overloading for functions.
Pro Tips
💡 Prefer fold expressions: They're more readable than recursive template unpacking and generate better error messages.
💡 Use static_assert: Add static_assert inside templates to give clear compile-time errors for unsupported types.
💡 Concepts (C++20): Use concept and requires instead of SFINAE for cleaner type constraints.
📋 Quick Reference
| Feature | Syntax |
|---|---|
| Variadic params | template <typename... Args> |
| Pack size | sizeof...(Args) |
| Fold expression | (args + ...) |
| if constexpr | if constexpr (condition) |
| Full specialization | template <> class X<int> |
| Non-type param | template <int N> |
Lesson Complete!
You've mastered advanced template techniques including variadic templates, fold expressions, and specialization. Next: STL Algorithm Mastery — transform, sort, find_if, and custom predicates.
Sign up for free to track which lessons you've completed and get learning reminders.