Lambda functions are a way of declaring an anonymous function, i.e. a function without a name.
The signature of a lambda function is as follows:
[capture list] (parameters) -> Return Type {};
Although the return type is optional and the compiler will work out the return type from the return value.
Lambda Examples
The following is a perfectly valid lambda function. It won’t do anything because it has not been called.
[] () { std::cout << "Hello Lambda World!" << std::endl; };
You can assign a lambda function to a variable and use that variable to call it.
auto func = [] () { std::cout << "Hello Lambda World!" << std::endl; };
func();
You can even call a lambda function directly by adding parenthesis after the definition.
[] () { std::cout << "Hello Lambda World!" << std::endl; }();
So far lambdas don’t really seem that useful, but where they really shine is when you need to pass a function into another function. Now, you can pass any function to a function that expects one but when not using lambdas the syntax is more cumbersome. With lambda functions, it’s as easy as
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
int main(){
std::vector<std::string> v {};
v.push_back("Hello");
v.push_back("Lambda");
v.push_back("World");
std::for_each(v.begin(), v.end(), [](std::string s){std::cout << s << std::endl; });
return 0;
}
The Capture List
The capture list allows a lambda function to capture variables from the parent scope. They can be captured by copy and by reference with the usual rules applying. For example in the code below a is passed as a copy and remains unaffected by changes in the parent scope and b is passed by reference an so is affected by the same changes.
#include <iostream>
int main(){
int a {10};
int b {20};
auto func = [a, &b] () { std::cout << a << ", " << b << std::endl;};
for (int i {}; i < 5; ++i) {
++a;
++b;
func();
}
return 0;
}
You can capture all variables by copy or reference by using an = or an & in your capture list.