> ## Documentation Index
> Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# C++ Variadic Template

A variadic template is a class, function, alias (C++11), or variable (C++14) template that accepts an arbitrary number of template arguments. This is achieved through the use of a **parameter pack**, which represents a comma-separated list of zero or more arguments.

The ellipsis operator (`...`) is the core syntactic element used to declare and expand parameter packs. Its placement determines whether it is defining a pack or expanding one.

## Supported Template Types

Variadic templates can be applied across four distinct template categories:

```cpp theme={"dark"}
#include <tuple>
#include <cstddef>

// 1. Class Template
template <typename... Ts>
class Tuple {};

// 2. Function Template
template <typename... Ts>
void process(Ts... args) {}

// 3. Alias Template (C++11)
template <typename... Ts>
using my_tuple = std::tuple<Ts...>;

// 4. Variable Template (C++14)
template <typename... Ts>
constexpr std::size_t size_v = sizeof...(Ts);
```

## Core Terminology and Syntax

1. **Template Parameter Pack:** Declared in the template parameter list. It represents zero or more types (or non-types/templates).
2. **Function Parameter Pack:** Declared in the function signature. It represents zero or more function arguments.
3. **Pack Expansion:** The process of unpacking the parameter pack into separate, comma-separated arguments.

```cpp theme={"dark"}
// 'Types' is a template parameter pack
template <typename... Types> 
// 'args' is a function parameter pack
void evaluate(Types... args) { 
    // 'args...' is a pack expansion
    targetFunction(args...); 
}
```

## Pack Expansion Mechanics

When a pack is expanded, the compiler duplicates the pattern preceding the ellipsis for each element in the pack, separating them with commas.

```cpp theme={"dark"}
#include <utility>

void consume(int, double); // Example target function

template <typename... Args>
void forward_all(Args&&... args) {
    // The pattern is 'std::forward<Args>(args)'
    // If Args contains {int, double}, this expands to:
    // consume(std::forward<int>(args1), std::forward<double>(args2));
    consume(std::forward<Args>(args)...); 
}
```

## Processing Parameter Packs

Because parameter packs cannot be indexed directly (e.g., `args[0]`), C++ provides specific mechanisms to iterate over or process the elements within a pack.

### 1. Recursive Instantiation (Pre-C++17)

The traditional method for processing a pack involves compile-time recursion. This requires two overloads: a base case to terminate the recursion, and a variadic template that isolates the first argument and recursively passes the remaining pack.

```cpp theme={"dark"}
void handle(int); // Example target function

// 1. Base case: invoked when the parameter pack is empty
void process() {}

// 2. Recursive step: peels off the first argument (Head) 
// and leaves the rest in the pack (Tail)
template <typename Head, typename... Tail>
void process(Head head, Tail... tail) {
    handle(head);      // Process the isolated argument
    process(tail...);  // Recursively expand the remaining pack
}
```

### 2. Fold Expressions (C++17)

C++17 introduced fold expressions, which apply a binary operator to all elements of a parameter pack directly, eliminating the need for recursive boilerplate.

There are four types of fold expressions:

* **Unary Right Fold:** `(pack op ...)` expands to `arg1 op (arg2 op arg3)`
* **Unary Left Fold:** `(... op pack)` expands to `(arg1 op arg2) op arg3`
* **Binary Right Fold:** `(pack op ... op init)` expands to `arg1 op (arg2 op (arg3 op init))`
* **Binary Left Fold:** `(init op ... op pack)` expands to `((init op arg1) op arg2) op arg3`

```cpp theme={"dark"}
#include <iostream>

template <typename... Args>
bool all_true(Args... args) {
    // Unary left fold using the logical AND operator
    return (... && args); 
}

template <typename... Args>
void print_all(Args... args) {
    // Unary right fold using the comma operator.
    // The pattern being expanded is 'void(std::cout << args << " ")'
    (void(std::cout << args << " "), ...); 
}
```

## Querying Pack Size

The `sizeof...` operator is used to determine the number of elements contained within a parameter pack at compile time. It yields a constant expression of type `std::size_t`.

```cpp theme={"dark"}
#include <cstddef>

template <typename... Args>
constexpr std::size_t get_argument_count() {
    return sizeof...(Args); // Returns the number of types in the pack
}
```

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor C++ Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
