I'm a C + +.
Have been reminding myself, I am engaged in C + +; But when c++11 out so long, I did not follow the team go, found very sorry for their identity, but also good, found that they have a period of time did not write C + + code. Today I saw the lambda expression in C + +, although the use of C #, but C + +, has been no use, also do not know how to use, on the poor even the lambda grammar can not understand. OK, here is a simple summary of the lambda in C + +, even if it is an account of their own, I am engaged in C + +, I am a C + + programmer. a simple code
I am also not a literary person, for the history of the lambda, as well as the Lambda and C + + of the source, I am not very familiar with the technical people, pay attention to the code to say things.
#include <iostream>
using namespace std;
int main ()
{
int a = 1;
int b = 2;
Auto Func = [=, &b] (int c)->int {return b + = a + C;};
return 0;
}
When I first saw this code, I was directly messy, directly do not understand AH. The above code, if you understand, the following content on the review at that time, if you do not understand, then go with me to sum up. Basic Syntax
In simple terms, a lambda function is a function, and its syntax is defined as follows:
[Capture] (parameters) mutable->return-type{statement}
[Capture]: Capture list. The capture list always appears at the beginning of the lambda function. In fact, [] is a lambda derivation. The compiler determines whether the next code is a lambda function based on the derivation. The capture list is able to capture variables in the context for use by the lambda function; (parameters): A list of parameters. Consistent with the parameter list of a normal function. If parameter passing is not required, it can be omitted together with the parentheses "()"; mutable:mutable modifier. By default, a lambda function is always a const function, and mutable can cancel its constant nature. When using this modifier, the argument list cannot be omitted (even if the argument is empty); ->return-type: return type. Declares the return type of a function in the form of a trace return type. We can also omit the symbol "->" when we do not need to return the value. In addition, if the return type is clear, the section can also be omitted to allow the compiler to deduce the return type; {statement}: function body. Content is the same as a normal function, but you can use all of the captured variables in addition to the parameters you can use.
The biggest difference from a normal function is that, in addition to the parameters that can be used, a lambda function can also access data in some contexts by capturing the list. Specifically, the capture list describes which data in the context can be used by a lambda, and how it is used (in a value-passing manner or by reference). Syntactically, the capture list is included in [], and the capture list consists of multiple snap items separated by commas. There are several forms of capturing a list: [Var] represents a value-passing method to catch variable var; [=] represents a variable in which the value is passed to capture all parent scopes (including this); [&var] denotes a reference pass-catch variable var; A variable (including this) that represents the way in which the reference is passed to catch all the parent scopes; [This] represents the way the value is passed to catch the current this pointer.
This refers to a parent scope, which is a block of statements containing a lambda function, saying that the popular point is the "{}" code block that contains the lambda. The capture list above can also be combined, for example: [=,&a,&b] means to capture variables A and B by reference, and to capture all other variables in a value-passing manner; [&,a,this] means that the variables a and this are captured in a value pass, and the reference is passed to catch all other variables.
It is worth noting, however, that the capture list does not allow variables to be repeatedly passed. The following examples are typical repetitions that result in compile-time errors. For example: [=,a] here has captured all the variables in the form of value, but repeated the catch of a, will be an error; [&,&this] Here & has captured all the variables by reference, and capturing this is also a repetition. use of Lambda
For the use of lambda, to tell you the truth, I don't have much to say, personally understand, in C + + before no lambda, we are so good to use, and do not have a lack of lambda C + + have any complaints, and now have lambda expression, just more convenient for us to write code. I do not know if you remember the C + + STL library in The Imitation function object, imitation functions for ordinary functions, an affine function can have an initialization state, which is specified by a parameter when declaring a functor object, and is generally stored in a private variable of an imitation function object; For functions that require a state, we typically do so using an imitation function, such as the following code:
#include <iostream> using namespace std;
typedef enum {add = 0, Sub, mul, Divi}type;
Class Calc {Public:calc int x, int y): m_x (x), m_y (y) {} int operator () (Type I) {
switch (i) {case Add:return m_x + m_y;
Case Sub:return m_x-m_y;
Case Mul:return m_x * m_y;
Case Divi:return m_x/m_y;
}} private:int m_x;
int m_y;
};
int main () {Calc addobj (10, 20); Cout<<addobj (ADD) <<endl;
It was found that the use of the enum type also changed and was more "strong" in c++11
return 0; }
Now that we have the tool for lambda, is it possible to rewrite the above implementation? Look at the code:
#include <iostream>
using namespace std;
typedef enum
{
add = 0,
Sub,
mul,
divi
}type;
int main ()
{
int a = ten;
int b =;
Auto Func = [=] (Type I)->int {
switch (i)
{case
add: return
a + b;
Case SUB: return
a-b;
Case MUL: Return
A * b;
Case DIVI: Return a/
b;
Cout<<func (ADD) <<endl;
}
The obvious effect, the code is simple, you write less code, but also to try C + + lambda expression Bar. about the wonderful things of the lambda.
Look at this section of code:
#include <iostream>
using namespace std;
int main ()
{
int j = Ten;
Auto By_val_lambda = [=]{return j + 1;};
Auto By_ref_lambda = [&]{return j + 1;};
cout<< "By_val_lambda:" <<by_val_lambda () <<endl;
cout<< "By_ref_lambda:" <<by_ref_lambda () <<endl;
++j;
cout<< "By_val_lambda:" <<by_val_lambda () <<endl;
cout<< "By_ref_lambda:" <<by_ref_lambda () <<endl;
return 0;
}
The results of the program output are as follows:
By_val_lambda:11
by_ref_lambda:11
by_val_lambda:11
by_ref_lambda:12
Do you have any idea ...? Then why is that? Why is the third output not 12?
In By_val_lambda, J is treated as a constant that will not change once it is initialized (it can be thought of as a constant with the same name as J in the parent scope), while in By_ref_lambda, J still uses the value in the parent scope. So, when using a lambda function, if the value that needs to be captured becomes a constant of the lambda function, we usually catch it by value, but instead, if the value that needs to be captured becomes a variable at the time the lambda function is run, it should be captured by reference.
A bit more dizzy code:
#include <iostream> using namespace std;
int main () {int val = 0; Auto CONST_VAL_LAMBDA = [=] () {val = 3;};
Wrong!!!
Auto MUTABLE_VAL_LAMBDA = [=] () mutable{val = 3;};
Mutable_val_lambda (); cout<<val<<endl;
0 Auto Const_ref_lambda = [Ampersand] () {val = 4;};
Const_ref_lambda (); cout<<val<<endl;
4 Auto MUTABLE_REF_LAMBDA = [ampersand] () mutable{val = 5;};
Mutable_ref_lambda (); cout<<val<<endl;
5 return 0; }
This code is primarily used to understand the mutable keyword in a lambda expression. By default, a lambda function is always a const function, and mutable can cancel its constant nature. As a rule, a const member function is the value of a non-static member variable that cannot be modified in a function body. For example, the lambda expression above can be considered as the following code of imitation functions:
Class Const_val_lambda
{public
:
const_val_lambda (int v): Val (v) {}
void operator () () const {val = 3;} Constant member function
private:
int val;
};
For the const member function, modify the non-static member variable, so there is an error. The way the reference is passed does not change the reference itself, but only changes the referenced value, so there is no error. are some tangled rules. Understand it slowly. Summary
For a lambda this kind of thing, some people use is very cool, but some people are not happy to look at. The beholder, the benevolent. In any case, you, as a programmer, will. This article is used to make up for the lack of awareness of the C + + lambda expression of the fault, lest in the future in other people's code to see the lambda, still do not understand this kind of thing, then lose the adult.
October 11, 2014 in Shenzhen.