# Cpp Templates

> When to activate: templates, template metaprogramming, SFINAE, concepts, variadic templates, fold expressions, type_traits, enable_if, constexpr if

- Skill: `mattakushi432/cpp-templates` (Agent Skill)
- Install (CLI): `npx skillmds@latest add mattakushi432/cpp-templates`
- Raw SKILL.md: https://api.skillmd.com/api/skills/mattakushi432/cpp-templates/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Mattakushi432 (https://skillmd.com/u/mattakushi432)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/mattakushi432/cpp-templates

---

# C++ Template Patterns

## Function and Class Templates

```cpp
// Function template
template<typename T>
T max_val(T a, T b) { return a > b ? a : b; }

// Class template with default
template<typename T, std::size_t N = 8>
class RingBuffer {
    std::array<T, N> data_;
    std::size_t head_ = 0, size_ = 0;
public:
    void push(T val) { data_[head_++ % N] = std::move(val); }
    T& front() { return data_[(head_ - size_) % N]; }
};
```

## C++20 Concepts (Preferred over SFINAE)

```cpp
#include <concepts>

// Define a concept
template<typename T>
concept Numeric = std::integral<T> || std::floating_point<T>;

// Constrain a function
template<Numeric T>
T square(T x) { return x * x; }

// Abbreviated function template (C++20)
auto add(Numeric auto a, Numeric auto b) { return a + b; }

// Requires clause for complex constraints
template<typename T>
requires std::copyable<T> && std::equality_comparable<T>
bool contains(const std::vector<T>& v, const T& val) {
    return std::ranges::find(v, val) != v.end();
}
```

## SFINAE (Pre-C++20 Compatibility)

```cpp
#include <type_traits>

// enable_if style
template<typename T, std::enable_if_t<std::is_integral_v<T>, int> = 0>
void process(T val) { /* integral version */ }

// C++17 if constexpr (preferred over tag dispatch)
template<typename T>
void serialize(const T& val) {
    if constexpr (std::is_arithmetic_v<T>) {
        write_numeric(val);
    } else if constexpr (std::is_same_v<T, std::string>) {
        write_string(val);
    } else {
        val.serialize(*this);  // assumes serialize() method
    }
}
```

## Variadic Templates

```cpp
// Parameter pack expansion
template<typename... Args>
void log(const char* fmt, Args&&... args) {
    std::printf(fmt, std::forward<Args>(args)...);
}

// Fold expressions (C++17)
template<typename... T>
auto sum(T... vals) { return (vals + ...); }       // unary right fold
auto product(T... vals) { return (1 * ... * vals); } // binary left fold

template<typename... Ts>
void print_all(Ts&&... args) {
    ((std::cout << args << ' '), ...);  // comma fold
}
```

## Type Traits and Metaprogramming

```cpp
// Conditional type
using IntOrFloat = std::conditional_t<sizeof(long) == 8, long, long long>;

// Type list operations
template<typename... Ts>
struct TypeList {};

template<typename TL>
struct Head;
template<typename T, typename... Ts>
struct Head<TypeList<T, Ts...>> { using type = T; };

// Detecting member existence (C++20 requires)
template<typename T>
concept HasSize = requires(T t) { { t.size() } -> std::convertible_to<std::size_t>; };
```

## Template Specialization

```cpp
// Primary template
template<typename T>
struct Serializer { static std::string to_json(const T& v); };

// Full specialization
template<>
struct Serializer<bool> {
    static std::string to_json(bool v) { return v ? "true" : "false"; }
};

// Partial specialization
template<typename T>
struct Serializer<std::vector<T>> {
    static std::string to_json(const std::vector<T>& v) {
        std::string result = "[";
        for (const auto& e : v) result += Serializer<T>::to_json(e) + ",";
        if (result.back() == ',') result.pop_back();
        return result + "]";
    }
};
```

