- Learning C++ Functional Programming
- Wisnu Anggoro
- 320字
- 2021-07-02 20:51:37
Capturing a value to the Lambda expression
In our previous Lambda expression examples, we keep the capturing part and the square bracket ([]) empty since the Lambda doesn't capture anything and doesn't have any extra member variable in the anonymous object generated by the compiler. We can also specify the object we want to capture in the Lambda expression by specifying it in this square bracket. Let's take a look at the following piece of code to go through the discussion:
/* lambda_capturing_by_value.cpp */
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
auto main() -> int
{
cout << "[lambda_capturing_by_value.cpp]" << endl;
// Initializing a vector containing integer element
vector<int> vect;
for (int i = 0; i < 10; ++i)
vect.push_back(i);
// Displaying the elements of vect
cout << "Original Data:" << endl;
for_each(
begin(vect),
end(vect),
[](int n){
cout << n << " ";
});
cout << endl;
// Initializing two variables
int a = 2;
int b = 8;
// Capturing value explicitly from the two variables
cout << "Printing elements between " << a;
cout << " and " << b << " explicitly [a,b]:" << endl;
for_each(
begin(vect),
end(vect),
[a,b](int n){
if (n >= a && n <= b)
cout << n << " ";
});
cout << endl;
// Modifying variable a and b
a = 3;
b = 7;
// Capturing value implicitly from the two variables
cout << "printing elements between " << a;
cout << " and " << b << " implicitly[=]:" << endl;
for_each(
begin(vect),
end(vect),
[=](int n){
if (n >= a && n <= b)
cout << n << " ";
});
cout << endl;
return 0;
}
In the preceding code, we will try to capture the value in the Lambda expression, explicitly and implicitly. Let's suppose we have two variables, a and b, and we want to explicitly capture the values, we can specify them in the Lambda expression using the [a,b] statement, and then using the values inside the function body. Moreover, if we wish to capture the value implicitly, just use [=] for the capturing part and then the expression will know which variable we intend to use when we specify them in the function body. If we run the preceding code, we will get the following output on the screen:

We can also mutate the state of the values we capture without modifying the value outside the Lambda expression function body. For this purpose, we can use the same techniques as used previously, and add the mutable keyword as shown in the following block of code:
/* lambda_capturing_by_value_mutable.cpp */
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
auto main() -> int
{
cout << "[lambda_capturing_by_value_mutable.cpp]" << endl;
// Initializing a vector containing integer element
vector<int> vect;
for (int i = 0; i < 10; ++i)
vect.push_back(i);
// Displaying the elements of vect
cout << "Original Data:" << endl;
for_each(
begin(vect),
end(vect),
[](int n){
cout << n << " ";
});
cout << endl;
// Initializing two variables
int a = 1;
int b = 1;
// Capturing value from the two variables
// without mutate them
for_each(
begin(vect),
end(vect),
[=](int& x) mutable {
const int old = x;
x *= 2;
a = b;
b = old;
});
// Displaying the elements of vect
cout << "Squared Data:" << endl;
for_each(
begin(vect),
end(vect),
[](int n) {
cout << n << " ";
});
cout << endl << endl;
// Displaying value of variable a and b
cout << "a = " << a << endl;
cout << "b = " << b << endl;
return 0;
}
The preceding code will double the element of the vect vector. It uses capturing by value in the Lambda expression and also the mutable keyword. As we can see, we passed the vector element by reference (int& x) and multiplied it by two, then changed the value of a and b. However, since we use the mutable keyword, the final result of a and b will remain the same, although, we have passed the vector by reference. The output on the console looks like the following screenshot:

If we want to change the value of the a and b variables, we have to use the Lambda expression to capture by reference. We can do this by passing the reference to the angle bracket in the Lambda expression, for instance, [&a, &b]. For more detail, let's take a look at the following piece of code:
/* lambda_capturing_by_reference.cpp */
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
auto main() -> int
{
cout << "[lambda_capturing_by_reference.cpp]" << endl;
// Initializing a vector containing integer element
vector<int> vect;
for (int i = 0; i < 10; ++i)
vect.push_back(i);
// Displaying the elements of vect
cout << "Original Data:" << endl;
for_each(
begin(vect),
end(vect),
[](int n){
cout << n << " ";
});
cout << endl;
// Initializing two variables
int a = 1;
int b = 1;
// Capturing value from the two variables
// and mutate them
for_each(
begin(vect),
end(vect),
[&a, &b](int& x){
const int old = x;
x *= 2;
a = b;
b = old;
});
// Displaying the elements of vect
cout << "Squared Data:" << endl;
for_each(
begin(vect),
end(vect),
[](int n) {
cout << n << " ";
});
cout << endl << endl;
// Displaying value of variable a and b
cout << "a = " << a << endl;
cout << "b = " << b << endl;
return 0;
}
The preceding code has the same behavior with the lambda_capturing_by_value_mutable.cpp file that will double the element of the vect vector. However, by capturing by reference, it now also modifies the value of a and b when they are processed in the for_each loop. The a and b values will be changed at the end of the code, as we can see in the following screenshot:

- 深入核心的敏捷開發:ThoughtWorks五大關鍵實踐
- JavaScript百煉成仙
- Production Ready OpenStack:Recipes for Successful Environments
- Python數據可視化之Matplotlib與Pyecharts實戰
- Python:Master the Art of Design Patterns
- SQL Server實用教程(SQL Server 2008版)
- 基于SpringBoot實現:Java分布式中間件開發入門與實戰
- C指針原理揭秘:基于底層實現機制
- 算法秘籍
- Clojure編程樂趣
- Building Web and Mobile ArcGIS Server Applications with JavaScript(Second Edition)
- Three.js Essentials
- 開源網絡地圖可視化:基于Leaflet的在線地圖開發
- Spring MVC Cookbook
- Learning RSLogix 5000 Programming