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

A generic lambda is a lambda expression whose function call operator is a member template. This occurs when the lambda uses `auto` type specifiers in its parameter list (introduced in C++14) or defines an explicit template parameter list (introduced in C++20). It instructs the compiler to synthesize a closure type containing a function call operator member template (`operator()`).

## Syntax Visualization

**C++14: Implicit Template Parameters**
Using `auto` in the parameter list implicitly makes the lambda generic. Each `auto` parameter represents a distinct, unnamed template type parameter.

```cpp theme={"dark"}
auto generic_lambda = [](auto x, auto y) {
    return x + y;
};
```

**C++20: Explicit Template Parameter Lists**
C++20 introduced the ability to explicitly declare template parameters within angle brackets `<>` immediately following the lambda introducer `[]`.

```cpp theme={"dark"}
auto explicit_generic_lambda = []<typename T, typename U>(T x, U y) {
    return x + y;
};
```

## Compiler Translation (Under the Hood)

When the compiler encounters a generic lambda, it synthesizes an unnamed closure class. The generic parameters are translated into a templated `operator()`.

The C++14 generic lambda `[](auto x, auto y) { return x + y; }` is structurally equivalent to the following compiler-generated class:

```cpp theme={"dark"}
class __CompilerGeneratedClosure {
public:
    // The call operator is a function call operator member template
    template <typename T1, typename T2>
    auto operator()(T1 x, T2 y) const {
        return x + y;
    }
    
    // State (captures) would be stored here as member variables
};
```

## Type Deduction and Qualifiers

The `auto` keyword in a generic lambda parameter list strictly follows template argument deduction rules. By default, `auto` deduces the base type by value, stripping top-level `const`, `volatile`, and reference qualifiers.

To modify the parameter type, standard reference and cv-qualifiers must be explicitly applied to the `auto` specifier. The `auto` placeholder deduces the base type `T`, while the explicit qualifiers determine the final parameter type:

```cpp theme={"dark"}
auto by_value     = [](auto x) {};        // 'auto' deduces T, parameter type is T
auto by_reference = [](auto& x) {};       // 'auto' deduces T, parameter type is T&
auto by_const_ref = [](const auto& x) {}; // 'auto' deduces T, parameter type is const T&
auto perfect_fwd  = [](auto&& x) {};      // 'auto' deduces T (or ref for lvalues), parameter type is T&&
```

## Variadic Generic Lambdas

Generic lambdas fully support parameter packs, enabling the creation of variadic closures. This is achieved by combining `auto` with the ellipsis `...` operator.

```cpp theme={"dark"}
auto variadic_lambda = [](auto&&... args) {
    // 'args' is a function parameter pack of forwarding references
};
```

This translates to a closure class with a variadic member function template:

```cpp theme={"dark"}
class __VariadicClosure {
public:
    template <typename... Ts>
    auto operator()(Ts&&... args) const {
        // ...
    }
};
```

## C++20 Explicit Template Parameter Lists

The C++20 explicit template syntax resolves specific structural limitations of the C++14 `auto` syntax, primarily regarding type enforcement and type extraction.

**1. Enforcing Identical Types**
In C++14, `[](auto a, auto b)` deduces two independent types. Enforcing that both arguments are of the exact same type required `static_assert` and `std::is_same_v`. C++20 allows direct enforcement:

```cpp theme={"dark"}
auto strict_lambda = []<typename T>(T a, T b) {
    // Both 'a' and 'b' are guaranteed to be of the exact same type 'T'
};
```

**2. Accessing the Underlying Type**
In C++14, extracting the type of an `auto` parameter for internal declarations required `decltype`. If the parameter was passed by reference, `decltype` yielded a reference type, which lacks nested types (like `::value_type`), necessitating type traits like `std::decay_t` or `std::remove_reference_t`. C++20 provides direct access to the type identifier.

```cpp theme={"dark"}
// C++14 approach
auto cpp14_lambda = [](auto& container) {
    // decltype(container) is a reference type. 
    // std::decay_t is required to access the nested ::value_type.
    using ValueType = typename std::decay_t<decltype(container)>::value_type;
};

// C++20 approach
auto cpp20_lambda = []<typename T>(std::vector<T>& container) {
    T new_element; // Direct access to the underlying type T
};
```

## C++20 Constrained Generic Lambdas (Concepts)

C++20 integrates Concepts with generic lambdas, allowing developers to constrain the types that the lambda can accept. This can be applied using either the constrained `auto` syntax or explicit template parameter lists.

**Constrained `auto` Syntax:**

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

auto constrained_auto_lambda = [](std::integral auto x, std::floating_point auto y) {
    // 'x' must be an integral type, 'y' must be a floating-point type
};
```

**Constrained Explicit Template Syntax:**

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

auto constrained_explicit_lambda = []<std::integral T>(T x, T y) {
    // Both 'x' and 'y' must be of the exact same integral type 'T'
};
```

If a constrained generic lambda is invoked with arguments that do not satisfy the specified concepts, the compiler rejects the invocation during overload resolution.

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