> ## 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++ Template Lambda

A C++ template lambda is a lambda expression that explicitly declares a template parameter list, introduced in C++20. It extends the C++14 generic lambda (which relies on `auto` parameters) by allowing developers to name the template parameters directly. This enables precise type constraints, exact type extraction, and simplified perfect forwarding without requiring `decltype` or `std::decay_t` boilerplate.

## Syntax Anatomy

The template parameter list is enclosed in angle brackets `< >` and is positioned immediately after the capture clause `[ ]` and before the function parameter list `( )`.

```cpp theme={"dark"}
[captures] <template_parameters> requires_clause (parameters) specifiers exception_attr -> return_type requires_clause { 
    // body 
}
```

**Basic Example:**

```cpp theme={"dark"}
auto explicit_generic = []<typename T>(T a, T b) {
    return a + b;
};
```

## Compiler Translation (The Closure Class)

Under the hood, the compiler translates a template lambda into an unnamed closure class containing a templated `operator()`.

The lambda expression above is functionally equivalent to the following compiler-generated structure:

```cpp theme={"dark"}
struct UnnamedClosureClass {
    template <typename T>
    auto operator()(T a, T b) const {
        return a + b;
    }
};
auto explicit_generic = UnnamedClosureClass{};
```

## Technical Mechanics vs. C++14 Generic Lambdas

In C++14, generic lambdas use `auto` to deduce types, which implicitly creates a template parameter for each `auto` argument. C++20 template lambdas solve specific mechanical limitations of the `auto` approach.

### 1. Enforcing Identical Types

With C++14 generic lambdas, enforcing that two parameters share the exact same type requires `static_assert` and type traits. Template lambdas enforce this at the signature level.

```cpp theme={"dark"}
// C++14: Implicitly creates <typename T1, typename T2>
auto cpp14_lambda = [](auto a, auto b) {
    static_assert(std::is_same_v<decltype(a), decltype(b)>);
};

// C++20: Explicitly creates <typename T>
auto cpp20_lambda = []<typename T>(T a, T b) {
    // a and b are guaranteed to be the same type
};
```

### 2. Perfect Forwarding

Forwarding an `auto` parameter in C++14 requires `decltype` to deduce the value category. Template lambdas allow direct use of the named template parameter `T`.

```cpp theme={"dark"}
// C++14
auto forward_cpp14 = [](auto&& arg) {
    return wrapper(std::forward<decltype(arg)>(arg));
};

// C++20
auto forward_cpp20 = []<typename T>(T&& arg) {
    return wrapper(std::forward<T>(arg));
};
```

### 3. Extracting Inner Types

When passing a templated container (like `std::vector`) to a lambda, C++14 requires `typename decltype(container)::value_type` to access the underlying element type. Template lambdas allow pattern matching on the parameter type directly.

```cpp theme={"dark"}
// C++14
auto process_cpp14 = [](const auto& container) {
    using ElementType = typename std::decay_t<decltype(container)>::value_type;
    ElementType temp = /* ... */;
};

// C++20
auto process_cpp20 = []<typename T>(const std::vector<T>& container) {
    T temp = /* ... */; // T is directly accessible
};
```

## Integration with C++20 Concepts

Template lambdas natively support C++20 Concepts for constrained template parameters. The constraints can be applied directly in the template parameter list or via a `requires` clause.

```cpp theme={"dark"}
// Constrained via concept in the template parameter list
auto constrained_lambda = []<std::integral T>(T value) {
    return value * 2;
};

// Constrained via trailing requires clause
auto requires_lambda = []<typename T>(T value) requires std::floating_point<T> {
    return value * 2.0;
};
```

## Parameter Pack Support

Template lambdas fully support variadic template parameter packs, allowing the lambda to accept an arbitrary number of arguments of varying types while retaining the ability to expand the pack explicitly.

```cpp theme={"dark"}
auto variadic_lambda = []<typename... Args>(Args&&... args) {
    return (std::forward<Args>(args) + ...); // Fold expression
};
```

<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>
