# Chapter 22 - Notes

## Lambda Expressions&#x20;

Lambda expressions are a compact way to define function objects without a name - which is why it is also sometimes referred to as **anonymous functions** (*anonymous* to mean without a name).

A lambda expression for simply printing an integer is as follows:

```cpp
[] (const int& number) { std::cout << number << std::endl; }
```

And its general form:

```cpp
[<capture group>] (<parameter list>) { <statement> }; 
```

## Capture Groups

The capture group component, `[]`, can be used to give a lambda expression **state** by capturing one or more **variables in the current scope**.&#x20;

```cpp
int divisor = 2; // initial value

// ...

auto element = find_if (
    begin of a range,
    end of a range,
    [divisor](int dividend){ return (dividend % divisor) == 0; } 
);
```

By default captured variables are **constant** and **copied by value**.&#x20;

### Modify captured variables

To allow modifications to the captured variables, use the `mutable` keyword:

```cpp
[stateVar1, stateVar2](Type& param) mutable { ... }
```

Note that the capture variables are still copied by value, and so changes made to it within the lambda expression will not take effect outside of it.&#x20;

To ensure modifications made to captured variables are also persisted outside of it, the variables need to be captured by reference:

```cpp
[&stateVar1, &stateVar2](Type& param){ ... }
```

### Capture all variables

To capture all variables in the local scope, use the following syntax:

```cpp
 [=]( ... ){ ... }
```

## Parameter List&#x20;

The parameter list component, `()`, can be used to specify zero or more parameters accepted by the lambda expression. The syntax is the same as a parameter list for a plain old function, each parameter separated by commas, and rules around `const` and references all apply the same.&#x20;

## Statement&#x20;

The compound statement component, `{}`, can hold one or more statements, each separated by a semicolon (`;`):

```cpp
[stateVar1, stateVar2](Type1 var1, Type2 var2) {
    return (value or expression);
}
```

## Explicit Return Types&#x20;

Note that the return type for lambda expressions need not be specified, the compiler will deduce this for you. However if you want to explicitly specify this to not leave disambiguation to the compiler, you can do so in the following:

```cpp
[...](...) -> RETURN_TYPE { ... }
```

If your lambda expression spans multiple lines, an explicit return type is required.&#x20;

## Full Syntax&#x20;

An example using the full syntax of a lambda expression:

```cpp
[&stateVariable1, stateVariable2](const Type1& param1, Type2 param2) mutable -> ReturnType {
    Statement_1;
    Statement_2;
    return (Expression or Value);
}
```

Capture group:

* `stateVariable1` is a variable captured by reference; modifications to this value within the lambda expression will persist outside of it as well.
* `stateVariable2` is a variable captured by value; modifications to this value will not persist outside of it.&#x20;

Parameter list:

* `param1` is a constant reference parameter of type `Type1` which can be used within the lambda expression
* `param2` is a value parameter of type `Type2` which can be used within the lambda expression

Keywords:

* The `mutable` keyword allows modifications to the `stateVariable1` and `stateVariable2` variables.
* The lambda expression's return type is `ReturnType`

Statements:

* The lambda expression has 3 statements, the last being a return statement returning either an expression or a value.&#x20;

## Function Objects vs Lambdas

| Lambda Expressions                                                                                                                                                                                                                                                                                                                                 | Function Objects                                                                                                                                                            |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <ul><li>Use when the of the function is simple, and is only used in one part of your application</li><li>Simple lambda functions can often be inlined by the compiler (<a href="https://stackoverflow.com/questions/13722426/why-can-lambdas-be-better-optimized-by-the-compiler-than-plain-functions">moreso than plain functions!</a>)</li></ul> | <ul><li>Use when the logic of the function and maintenance of state is complex </li><li>Use when the function might be re-used in other parts of your application</li></ul> |
