Skip to content

Ch14: Lambda functions

TL;DR: Anonymous Functionality: Lambda functions provide inline anonymous functions that can be declared and executed on the fly or stored in variables.

โšก Quick Reference

#include <iostream>

int main() {
    // [capture](params) -> ret { body }; - Full lambda signature.
    auto full_lambda = [](double a, double b) -> double { return a + b; };

    // auto func = []{ ... }; - Assign lambda to an auto variable.
    auto simple_lambda = []() { std::cout << "Simple" << std::endl; };
    simple_lambda();

    // []{ ... }(); - Declare and immediately invoke a lambda.
    []() { std::cout << "One-shot" << std::endl; }();

    int a = 10, b = 20;
    // [a, b] - Capture specific variables by value.
    auto val_lambda = [a, b]() { return a + b; };

    // [&a, &b] - Capture specific variables by reference.
    auto ref_lambda = [&a, &b]() { a += 10; };

    // [=] - Capture all outer variables by value.
    auto capture_all_val = [=]() { return a + b; };

    // [&] - Capture all outer variables by reference.
    auto capture_all_ref = [&]() { a = 100; };

    // [] -> int { ... } - Explicitly specify the lambda return type.
    auto forced_ret = []() -> int { return 42; };

    // Executing lambda immediately with custom parameters
    double sum = [](double x, double y){ return x + y; }(10.5, 20.5);

    return 0;
}

๐Ÿง  Core Concepts

  • Anonymous Functionality: Lambda functions provide inline anonymous functions that can be declared and executed on the fly or stored in variables.
  • Variable Capture: Lambdas must capture outer variables via [] to access them, either by copy/value ([=]) or by reference ([&]).
  • Return Type Deduction: The compiler automatically infers a lambda's return type, but developers can specify it explicitly using suffix return notation ->.

โš ๏ธ Pitfalls (Quick Scan)

Mistake Fix
Declaring a lambda without invoking it or saving its handle Invoke the lambda immediately with () or save it in an auto variable
Accessing outer variables in a lambda body without capturing them Add variables explicitly to the capture list ([]) or use default captures
Expecting updates to outer variables to reflect in value-captured copies Capture variables by reference ([&]) if they must reflect runtime updates
Allowing references captured by a lambda to outlive their source variables Ensure referenced variables outlive the lifecycle of the calling lambda
Specifying a narrower explicit return type (e.g., ` The returned value is silently truncated, resulting in loss of precision
Passing mismatching types to lambda parameters Ensure argument types match lambda parameter definitions exactly

๐Ÿ“– Full Details

Cause โ†’ Effect โ†’ Fix with timestamp (click to expand) * **Declaring a lambda without invoking it or saving its handle** -> **The lambda code compiles but never runs, producing no output** -> **Invoke the lambda immediately with `()` or save it in an `auto` variable (00:04:17)** * **Accessing outer variables in a lambda body without capturing them** -> **Compile-time error stating that local variables cannot be referenced** -> **Add variables explicitly to the capture list (`[]`) or use default captures (00:15:51)** * **Expecting updates to outer variables to reflect in value-captured copies** -> **The lambda continues using the copy frozen at the moment of creation** -> **Capture variables by reference (`[&]`) if they must reflect runtime updates (00:14:30)** * **Allowing references captured by a lambda to outlive their source variables** -> **Undefined behavior or memory access crashes when reference is dereferenced** -> **Ensure referenced variables outlive the lifecycle of the calling lambda (00:18:30)** * **Specifying a narrower explicit return type (e.g., `-> int`) than expression results** -> **The returned value is silently truncated, resulting in loss of precision** -> **Match the return type to expression outcomes to prevent implicit narrowing (00:12:27)** * **Passing mismatching types to lambda parameters** -> **Compiler silently performs implicit type conversion, potentially losing data** -> **Ensure argument types match lambda parameter definitions exactly (00:07:56)**

๐Ÿ“Ž Repo Files

  • 21.LambdaFunctions/21.2DeclaringAndUsingLambdas/main.cpp
  • 21.LambdaFunctions/21.3CaptureLists/main.cpp
  • 21.LambdaFunctions/21.4CaptureAllLists/main.cpp
  • 22.FunctionsTheMisfits/22.2StaticVariables/main.cpp
  • 22.FunctionsTheMisfits/22.3InlineFunctions/main.cpp
  • 22.FunctionsTheMisfits/22.4RecursiveFunctions/main.cpp
  • 23.FunctionCallStackD_ebugging/23.4D_ebuggingInV_S_C0de/main.cpp
  • 23.FunctionCallStackD_ebugging/23.7D_ebuggingArraysLoopsAndPointers/main.cpp