Learn All About Lambda Expression In C++ In Simple Terms.
Lambda expression is the newest concept in C++ that was introduced from C++11 onwards.
In this tutorial, we will learn about lambdas in C++. We will also discuss how lambdas can be defined and used in the program.
=> Check The Complete C++ Training Series Here.
Table of Contents:
Lambda Expressions/Functions
Lambdas, as they are commonly called, are basically small inline snippets of code that can be used inside functions or even function call statements. They are not named or reused.
We can declare lambdas as “auto” and use them anywhere in the program.
How To Use/Write Lambdas?
The general syntax of defining lambdas is as follows:
(Capture clause) (parameter_list) mutable exception ->return_type { Method definition; }
Capture closure: Lambda introducer as per C++ specification.
Parameter list: Also called as lambda declarations. Is optional and is similar to the parameter list of a method.
Mutable: Optional. Enables variables captured by a call by value to be modified.
exception: Exception specification. Optional. Use “noexcept” to indicate that lambda does not throw an exception.
Return_type: Optional. The compiler deduces the return type of the expression on its own. But as lambdas get more complex, it is better to include return type as the compiler may not be able to deduce the return type.
Method definition: Lambda body.
A capture clause of lambda definition is used to specify which variables are captured and whether they are captured by reference or by value.
An empty capture closure [ ], indicates that no variables are used by lambda which means it can only access variables that are local to it.
The “capture-default” mode indicates how to capture outside the variables referenced in Lambda:
- The capture closure [&] means the variables are captured by reference.
- The capture closure [=] indicates that the variables are captured by value.
If we have a capture-default & a capture clause, then we cannot have an identifier in the capture of that particular capture can have the & identifier. Similarly, if the capture clause contains capture-default =, then the capture clause cannot have the form = identifier. Also, an identifier or ‘this’ cannot appear more than once in the capture clause.
This should be clear from the following Examples.
[&sum, sum_var] //OK, explicitly specified capture by value [sum_var, &sum] //ok, explicitly specified capture by reference [&, &sum_var] // error, & is the default still sum_var preceded by & [i, i] //error, i is used more than once
Here, sum, sum_var and I are the variables to be captured and used in lambda.
Given below is a basic Example of a Lambda Expression in C++.
#include <iostream> #include <string> using namespace std; int main() { auto sum = [](int a, int b) { return a + b; }; cout <<"Sum of two integers:"<< sum(5, 6) << endl; return 0; }
Output:
Sum of two integers:11
Here we have inline lambda expression to calculate the sum of two values. We have specified the type of values a and b as integers.
One problem with the above code is that it only works for integers. If later in the program, we want to add two doubles or strings or any other types, we will have to have those many lambdas. This is not an efficient way of programming.
We can overcome this problem by using template parameters. This makes lambdas generalized for all data types. This is done from C++14 onwards.
So the program above will be modified as follows:
#include <iostream> #include <string> using namespace std; int main() { // generalized lambda auto sum = [](auto a, auto b) { return a + b; }; cout <<"Sum(5,6) = "<< sum(5, 6) << endl; // sum of two integers cout <<"Sum(2.0,6.5) = "<<sum(2.0, 6.5) << endl; // sum of two float numbers cout <<"Sum((string(\"SoftwareTesting\"), string(\"help.com\")) = "<<sum(string("SoftwareTesting"), string("help.com")) << endl; // sum of two strings return 0; }
Output:
Sum(5,6) = 11
Sum(2.0,6.5) = 8.5
Sum((string(“SoftwareTesting”), string(“help.com”)) = SoftwareTestinghelp.com
Thus in this program, we have used a generic lambda sum, which can be used to find the sum of the two objects of any type. Note that we have used ‘auto’ keyword to indicate that the data type of the parameter will be deduced based on the data.
To demonstrate the usage of this lambda, we have used it with three different data types, int, float, and string. From the output, we know that according to the type of data, sum operation is carried out. For Example, when we supply string parameters to lambda sum, it concatenates the two strings.
Conclusion
We have come to the end of this tutorial on lambda expressions in C++. This is the newest concept in C++ and can be very helpful when we need to execute a small snippet of code inline. Lambdas can also be made generic and used for all data types.
In our upcoming tutorial, we will discuss some of the additional topics in C++ like time, standard input/output and logging.
=> Read Through The Popular C++ Training Series Here.