Chapter 22 - Notes
Lambda Expressions
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:
[] (const int& number) { std::cout << number << std::endl; }And its general form:
[<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.
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.
Modify captured variables
To allow modifications to the captured variables, use the mutable keyword:
[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.
To ensure modifications made to captured variables are also persisted outside of it, the variables need to be captured by reference:
[&stateVar1, &stateVar2](Type& param){ ... }Capture all variables
To capture all variables in the local scope, use the following syntax:
[=]( ... ){ ... }Parameter List
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.
Statement
The compound statement component, {}, can hold one or more statements, each separated by a semicolon (;):
[stateVar1, stateVar2](Type1 var1, Type2 var2) {
return (value or expression);
}Explicit Return Types
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:
[...](...) -> RETURN_TYPE { ... }If your lambda expression spans multiple lines, an explicit return type is required.
Full Syntax
An example using the full syntax of a lambda expression:
[&stateVariable1, stateVariable2](const Type1& param1, Type2 param2) mutable -> ReturnType {
Statement_1;
Statement_2;
return (Expression or Value);
}Capture group:
stateVariable1is a variable captured by reference; modifications to this value within the lambda expression will persist outside of it as well.stateVariable2is a variable captured by value; modifications to this value will not persist outside of it.
Parameter list:
param1is a constant reference parameter of typeType1which can be used within the lambda expressionparam2is a value parameter of typeType2which can be used within the lambda expression
Keywords:
The
mutablekeyword allows modifications to thestateVariable1andstateVariable2variables.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.
Function Objects vs Lambdas
Lambda Expressions
Function Objects
Use when the of the function is simple, and is only used in one part of your application
Simple lambda functions can often be inlined by the compiler (moreso than plain functions!)
Use when the logic of the function and maintenance of state is complex
Use when the function might be re-used in other parts of your application
Last updated
Was this helpful?