A functor or function objects is an object or structure that can be called like a function by overloading the function call
Details
Lambdas are basically anonymous function objects generated right at the location where it's invoked or passed as an argument to a function. Lambdas are game changer since they seamlessly integrate into stl algorithms, concurrency objects and more.
The syntax for Lambdas is as below.
[capture] (parameters)optional mutableoptional exception-Specoptional -> trailing return Typeoptional
{
definition of method
}
Except for the lambda introducer ([]) that contain captured local variables, all of the other items in the syntax are optional.
Following is a minimum lambda expression, calling itself.
[] //introducer
// no parameters {time_t curr_time;curr_time = time(NULL);tm *tm_local = localtime(&curr_time); size_t h = tm_local->tm_hour; cout << "Hello, "; if (h > 4 && h < 12) cout << "Good Morning"; else if (h > 11 && h < 17) cout << "Good Afternoon"; else if (h > 16 ) cout << "Good Evening"; cout << "!" << endl;
} //body(); //calling itself!
//prints @ 3 am : Hello, Good Evening!
The following describes it in detail:
- capture clause (Also known as the lambda-introducer)
- parameters (Also known as the lambda declarator)
- mutable specification.
- exception-specification.
- trailing-return-type.
- lambda definition.
capture
Unlike a normal function, a lambda can also to refer to local variables. It can access them either as read only value or as a reference as described below.
- [=] captures all local variables as value readonly
- [&] captures all local variables as value readwrite
- [i,j,&k] captures local variables i and j as value readonly and k as value readwrite
- [=,&i] captures all local variables as value readonly except i
- [&,=i] captures all local variables as value readwrite except i
- [this] captures all local variables as value readonly
- [v...] captures variadic variables
If the captured variables are modified, value captured variables do not retain modified value and revert back to original after the call; reference captured variables retain modified values after the call.
Global variables and static variables need not be captured. They can be accessed as is.
This is demonstrated in the example 2.
parameters
Parameters for a lambda are similar to those of normal functions,
This is depicted in the example 3.
mutable
This keyword should be used if value captured variables are modified in the implementation.
This is demonstrated in the example 2.
exception specification
noexcept exception specification can be used to indicate that the lambda expression doesn't throw any exceptions. As with ordinary functions, the compiler generates warning if a lambda expression declares the noexcept exception specification and the lambda body throws an exception.
//compiler warnings []() noexcept { throw 5; }();
trailing return type
The return type for a lambda is specified using a C++ feature named trailing return type. This specification is optional. Without the trailing return type, the return type of the underlying function is effectively auto, and it is deduced from the type of the expressions in the body's return statements.
This is depicted in the example 4.
Lambda in action
Following are some examples where lambdas can be used in stl and concurrency.
This is depicted in the example 5.
The following example demonstrates usage of recursive lambda expression. note auto cannot be used to store lambda expression.
function<void(int)> fib = [t1=0, t2 = 1,t=0] (int n) mutable { if (n>0) { cout << t1 << " "; t = t2; t2 += t1; t1 = t; fib(n-1); } else cout << " = " << t1 ; };fib(5); //0 1 1 2 3 = 7fib(9); //0 1 1 2 3 5 8 13 21 = 54
Summary of Examples
Name | Description | github | wandbox |
---|---|---|---|
Example | Generic Functor | source output | source + output |
Example 2 | Lambda - Capture and mutable | source output | source + output |
Example 3 | Lambda - Parameters | source output | source + output |
Example 4 | Lambda - Trailing return type | source output | source + output |
Example 5 | Lambda - in Action | source output | source + output |
Example 6 | Predefined functors | source output | source + output |
No comments:
Post a Comment