Courses/C++/Templates Deep Dive

    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

    Try it Yourself »
    C++
    #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 value

    Variadic Templates & Folds

    Build functions that accept any number of arguments

    Try it Yourself »
    C++
    #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

    Try it Yourself »
    C++
    #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

    FeatureSyntax
    Variadic paramstemplate <typename... Args>
    Pack sizesizeof...(Args)
    Fold expression(args + ...)
    if constexprif constexpr (condition)
    Full specializationtemplate <> class X<int>
    Non-type paramtemplate <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.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service