Lambda expressions are anonymous functions introduced in C++11 that allow for the creation of inline functions without the need for a separate function declaration. They provide a concise syntax for defining functions at the point of use, making code more expressive and readable.
Lambda expressions offer a powerful way to write more compact and maintainable code by encapsulating functionality directly where it’s needed. They are widely used in modern C++ programming for various tasks such as sorting, filtering, and event handling.
Lambda expressions offer a powerful way to write more compact and maintainable code by encapsulating functionality directly where it’s needed. They are widely used in modern C++ programming for various tasks such as sorting, filtering, and event handling.
[]
.[]
indicate no variable capture.[capture-list]
: Variables to capture by value.[&capture-list]
: Variables to capture by reference.[=, &capture-list]
: Captures all surrounding variables by value and specific variables by reference.()
.[](int x, double y)
takes two parameters, an integer x
and a double y
.-> return_type
: Explicitly specifies the return type.{}
.
#include
int main() {
int x = 5;
int y = 10;
// Lambda capturing x by value (copy)
auto add = [x](int a) {
return x + a;
};
int result = add(y); // result = 15 (5 + 10)
std::cout << "Result: " << result << std::endl;
return 0;
}
// output //
Result: 15
x
by value, creating a copy within the lambda’s scope.add(y)
, the value of y
(10) is added to the captured copy of x
(5), giving 15.
#include
int main() {
int x = 5;
// Lambda capturing x by reference
auto increment = [&x]() {
x++;
};
increment(); // Modifies the original x
std::cout << "x after increment: " << x << std::endl;
return 0;
}
// output //
x after increment: 6
x
by reference ([&x]
), allowing modification of the original variable in the outer scope.increment()
increments the original x
to 6.
#include
int main() {
int x = 5;
int y = 10;
// Lambda capturing all surrounding variables by value
auto sum = [=]() {
return x + y;
};
int result = sum(); // result = 15
std::cout << "Result: " << result << std::endl;
return 0;
}
// output //
Result: 15
[=]
captures all surrounding variables (in this case, x
and y
) by value within the lambda.
#include
int main() {
int x = 5;
// Lambda capturing x by value (trying to modify it)
auto increment = [x]() mutable { // mutable keyword allows modification
x++; // This would normally cause an error if mutable is not used
};
increment();
std::cout << "x after increment: " << x << std::endl;
return 0;
}
// output //
x after increment: 5
In the provided code, a lambda expression named increment
is defined to capture the variable x
by value. The mutable
keyword is used to indicate that the lambda function can modify its captured variables, even if they were captured by value.
However, despite using the mutable
keyword, the lambda function inside increment
attempts to modify the captured variable x
by incrementing it. This modification would normally be allowed due to the use of mutable
.
However, since the lambda function captures x
by value, any modifications made to x
inside the lambda are local to the lambda’s scope and do not affect the original variable x
declared in the main()
function. Therefore, the output remains 5
, as the original value of x
remains unchanged despite the attempted modification inside the lambda function.
Lambdas excel at working with function pointers, providing a concise way to define anonymous functions on the fly.
#include
#include // for std::function
int add(int x, int y) {
return x + y;
}
int main() {
// Function pointer to an add function
int (*fptr)(int, int) = add;
// Lambda equivalent to the add function
std::function lambda = [](int x, int y) { return x + y; };
int result1 = fptr(5, 10); // result1 = 15 (using function pointer)
int result2 = lambda(3, 8); // result2 = 11 (using lambda)
std::cout << "Result1 (fptr): " << result1 << std::endl;
std::cout << "Result2 (lambda): " << result2 << std::endl;
return 0;
}
// output //
Result1 (fptr): 15
Result2 (lambda): 11
add
function and a function pointer fptr
to it.add
.fptr
and the lambda are used to perform addition, achieving the same result.Lambda expressions are particularly useful with the Standard Template Library (STL) algorithms like std::sort
, std::find
, and std::for_each
. They allow you to define custom sorting criteria, search conditions, or actions to be performed on elements within the algorithm.
#include
#include
#include
struct Person {
std::string name;
int age;
};
int main() {
std::vector people = {
{"Alice", 30}, {"Bob", 25}, {"Charlie", 35}
};
// Sort people by age in descending order
std::sort(people.begin(), people.end(), [](const Person& p1, const Person& p2) {
return p1.age > p2.age;
});
for (const Person& person : people) {
std::cout << person.name << " (" << person.age << ")" << std::endl;
}
return 0;
}
// output //
Charlie (35)
Alice (30)
Bob (25)
Person
struct is defined to represent names and ages.std::sort
algorithm is used to sort the people
vector.Person
objects as arguments and compares their ages using the greater than operator (>
) to achieve descending order.Lambdas can capture variables from their surrounding scope, creating closures. These captured variables persist even after the lambda’s defining scope has ended, as long as the lambda object itself is alive. This allows for interesting use cases where the lambda’s behavior is influenced by the captured state.
#include
int main() {
int startingValue = 5;
// Lambda capturing startingValue by value
auto increment = [startingValue]() {
startingValue++; // Modifies the captured copy of startingValue
return startingValue;
};
int result1 = increment(); // result1 = 6
int result2 = increment(); // result2 = 7 (captured value persists)
std::cout << "Result1: " << result1 << std::endl;
std::cout << "Result2: " << result2 << std::endl;
return 0;
}
// output //
Result1: 6
Result2: 7
startingValue
is captured by value ([startingValue]
) within the lambda.increment
multiple times modifies the captured copy of startingValue
, demonstrating closure behavior.Lambda expressions in C++ provide a concise and powerful way to define inline functions, improving code readability and expressiveness. By capturing variables from the enclosing scope and supporting advanced features like mutable specifier and return type deduction, lambda expressions enable developers to write more flexible and efficient code.Happy coding !❤️