官术网_书友最值得收藏!

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:

主站蜘蛛池模板: 新龙县| 芦溪县| 固始县| 桦甸市| 太仆寺旗| 娄底市| 美姑县| 景泰县| 玉门市| 梨树县| 疏勒县| 永济市| 民丰县| 措勤县| 壤塘县| 阳信县| 常熟市| 沧源| 普兰县| 兴业县| 莲花县| 西安市| 通许县| 碌曲县| 廉江市| 屏南县| 革吉县| 静乐县| 乐安县| 毕节市| 都安| 历史| 海宁市| 明光市| 东方市| 贡嘎县| 墨江| 东乡族自治县| 嘉鱼县| 越西县| 奎屯市|