
- C++ Home
- C++ Overview
- C++ Environment Setup
- C++ Basic Syntax
- C++ Comments
- C++ Hello World
- C++ Omitting Namespace
- C++ Tokens
- C++ Constants/Literals
- C++ Keywords
- C++ Identifiers
- C++ Data Types
- C++ Numeric Data Types
- C++ Character Data Type
- C++ Boolean Data Type
- C++ Variable Types
- C++ Variable Scope
- C++ Multiple Variables
- C++ Basic Input/Output
- C++ Modifier Types
- C++ Storage Classes
- C++ Numbers
- C++ Enumeration
- C++ Enum Class
- C++ References
- C++ Date & Time
- C++ Operators
- C++ Arithmetic Operators
- C++ Relational Operators
- C++ Logical Operators
- C++ Bitwise Operators
- C++ Assignment Operators
- C++ sizeof Operator
- C++ Conditional Operator
- C++ Comma Operator
- C++ Member Operators
- C++ Casting Operators
- C++ Pointer Operators
- C++ Operators Precedence
- C++ Unary Operators
- C++ Control Statements
- C++ Decision Making
- C++ if Statement
- C++ if else Statement
- C++ Nested if Statements
- C++ switch Statement
- C++ Nested switch Statements
- C++ Loop Types
- C++ while Loop
- C++ for Loop
- C++ do while Loop
- C++ Foreach Loop
- C++ Nested Loops
- C++ break Statement
- C++ continue Statement
- C++ goto Statement
- C++ Strings
- C++ Strings
- C++ Loop Through a String
- C++ String Length
- C++ String Concatenation
- C++ String Comparison
- C++ Functions
- C++ Functions
- C++ Multiple Function Parameters
- C++ Recursive Function
- C++ Return Values
- C++ Function Overloading
- C++ Function Overriding
- C++ Default Arguments
- C++ Arrays
- C++ Arrays
- C++ Multidimensional Arrays
- C++ Pointer to an Array
- C++ Passing Arrays to Functions
- C++ Return Array from Functions
- C++ Structure & Union
- C++ Structures
- C++ Unions
- C++ Pointers
- C++ Pointers
- C++ Dereferencing
- C++ Modify Pointers
- C++ Class and Objects
- C++ Object Oriented
- C++ Classes & Objects
- C++ Class Member Functions
- C++ Class Access Modifiers
- C++ Static Class Members
- C++ Static Data Members
- C++ Static Member Function
- C++ Inline Functions
- C++ this Pointer
- C++ Friend Functions
- C++ Pointer to Classes
- C++ Constructors
- C++ Constructor & Destructor
- C++ Default Constructors
- C++ Parameterized Constructors
- C++ Copy Constructor
- C++ Constructor Overloading
- C++ Constructor with Default Arguments
- C++ Delegating Constructors
- C++ Constructor Initialization List
- C++ Dynamic Initialization Using Constructors
- C++ Inheritance
- C++ Inheritance
- C++ Multiple Inheritance
- C++ Multilevel Inheritance
- C++ Object-oriented
- C++ Overloading
- C++ Polymorphism
- C++ Abstraction
- C++ Encapsulation
- C++ Interfaces
- C++ Virtual Function
- C++ Pure Virtual Functions & Abstract Classes
- C++ File Handling
- C++ Files and Streams
- C++ Reading From File
- C++ Advanced
- C++ Exception Handling
- C++ Dynamic Memory
- C++ Namespaces
- C++ Templates
- C++ Preprocessor
- C++ Signal Handling
- C++ Multithreading
- C++ Web Programming
- C++ Socket Programming
- C++ Concurrency
- C++ Advanced Concepts
- C++ Lambda Expression
- C++ unordered_multiset
Lambda Expression in C++
Lambda Expression
A lambda expression in C++11 allows the user to define an anonymous function (a function without any name) inline, which captures variables from the surrounding scope. This makes them a powerful feature for various use cases, like callbacks, sorting, functional programming, etc.
Syntax
Here is the syntax of lambda expression in C++:
[capture](parameters) -> return_type { function_body }
Where,
- capture specifies which variables from the outer scope are captured. It captures variables by value, by reference, or by both methods.
- parameters are the input parameters for lambda.
- return_type defines the return type of the lambda function. If the return type needs to be explicitly defined, it will follow this -> symbol.
- body is the main body of the lambda, where function logic is written.
Example of Lambda Expression
In the following example, a lambda expression is used to add two numbers and return the result:
#include <iostream> int main() { // Define a lambda expression to add two numbers auto add = [](int a, int b) { return a + b; }; // Call the lambda expression int result = add(5, 3); std::cout << "The sum of 5 and 3 is: " << result << std::endl; return 0; }
Output
The sum of 5 and 3 is: 8
Capturing Variables in Lambda Expression
Capturing variables in lambda expressions allows lambda to access variables from its surrounding scope. By a capture clause, a lambda can capture variables from its surrounding scope and allow it to use those variables inside the lambda body.
Types of Variable Capture:
1. Capture by value ([x])
It captures the variables by values, which means lambda gets a copy of the variables and further cannot modify the original variable outside the lambda.
[x](parameters) -> return_type { body }
2. Capture by reference ([&x])
It captures the variables by reference, which means here the lambda can access and modify the original variables.
[&x](parameters) -> return_type { body }
3. Capture Specific Variables ([x, &y])
This allows you to mix capture types in the same lambda. Here, the user can specify which variables to capture by value or reference.
[x, &y](parameters) -> return_type { body }
4. Captures all variables by value ([=])
It captures all variables in the surrounding scope by value.
[=](parameters) -> return_type { body }
5. Captures all variables by reference ([&])
It captures all variables in the surrounding scope by reference.
[&](parameters) -> return_type { body }
Capture this by reference ([this])
It captures this
pointer (a reference to the current object) in a lambda expression. It is useful when the user needs to access member variables or functions from within a lambda in a class method.
6. Capture by Mixed Modes
- [=, &x] ,It captures all variables by value and x variable by reference.
- [&, x] ,It captures all variables by reference and x by value.
- [=, this] ,It captures this pointer by value and all other variables by value.
Return Types in Lambda Expressions
In C++, lambda expressions return the value just like regular functions, and its return type can be automatically deduced by the compiler or explicitly specified by the programmer.
1. Automatic Return Type Deduction
In this, the compiler deduces the return type based on the return expression inside the lambda.
a) Implicit Return Type
In this, the return type is based on the return expression, which means users don't need to explicitly specify the return type; it will automatically be inferred from the type of the expression.
[capture](parameters) { return expression; }
b) Returning References
It returns references to variables or values; for this, make sure that the referenced variable stays in scope for the lifetime of the lambda.
[capture](parameters) -> type& { return reference; }
c) Returning Pointers
A lambda can also return a pointer to a variable or dynamically allocated memory.
[capture](parameters) -> type* { return pointer; }
d) Type Deduction with auto
Here, you can also use an auto
keyword for the return type, and the compiler will deduce the correct return value type based on an expression.
[capture](parameters) -> auto { return value; }
2. Explicit Return Type
In this, if the user wants to specify lambda's return type explicitly, then use -> return_type
syntax. This is useful when working with any complex types and when the return type isn't obvious.
[capture](parameters) -> return_type { return expression; }
Example
#include <iostream> using namespace std; int main() { int x = 5; int y = 10; auto my_lambda = [=, &x]() -> int { cout << "Inside lambda:" << endl; // can't modify 'y' as it's captured by value // Modifying 'x' as it's captured by reference x += 10; cout << "Captured 'x' by reference inside lambda: " << x << endl; // Captured 'y' by value, so it can't be modified here // simple operation with 'y' and a local value int sum = y + 5; cout << "Captured 'y' by value inside lambda: " << y << endl; cout << "Sum of 'y' and 5 inside lambda: " << sum << endl; return sum; }; // Call the lambda int result = my_lambda(); cout << "Result returned from lambda: " << result << endl; cout << "Value of 'x' outside lambda after modification: " << x << endl; cout << "Value of 'y' outside lambda (no modification): " << y << endl; return 0; }
When the above code is compiled and executed, it produces the following result −
Inside lambda: Captured 'x' by reference inside lambda: 15 Captured 'y' by value inside lambda: 10 Sum of 'y' and 5 inside lambda: 15 Result returned from lambda: 15 Value of 'x' outside lambda after modification: 15 Value of 'y' outside lambda (no modification): 10
Recursive Lambdas
In C++, recursive lambda is the lambda function that calls itself over again and again during its execution until it reaches its base case. As lambda by default cannot call themselves directly, because they don't have a name. So for this, we can make lambda recursive by using a function pointer or std::function
.
Example
#include <iostream> #include <functional> // for std::function using namespace std; int main() { // Defining the recursive lambda using std::function std::function<int(int)> factorial = [&](int n) -> int { if (n <= 1) return 1; // Base case return n * factorial(n - 1); // Recursive call }; cout << "Factorial of 5: " << factorial(5) << endl; }
When the above code is compiled and executed, it produces the following result −
Factorial of 5: 120