What is a lambda?
C + + 11 Adds a very important feature-theLambda expression. Battalion Camp (Camp David) brothers are very familiar with objective-c, many people more than block love, the various callback functions, proxies all use it to achieve. Even some people choose to use Fbkvocontroller, Blockskit and other open source framework to change the KVO, control event processing to the block solution. The reason is simple, convenient, intuitive, the definition and use of functions appear in the same place. The lambda expression here is actually very similar to block, but if you compare it with the swift language closure, it's one thing. Let's look at some sample code for lambda and block.
1. The block sample code for OBJECTIVE-C, which uses a ^
block type, is generally similar to the definition of a function pointer.
#import <Foundation/Foundation.h>int main(){ void (^block)() = ^void() { NSLog(@"In block"); }; block(); return 0;}
Compile run:
$ clang main.m -framework Foundation$ ./a.out 2015-01-28 14:17:52.763 a.out[9901:165707] In block
2. Swift closures, parameter lists, return value types, and so on are all written inside curly braces {}
.
let closure = { () -> Void in println("In swift")}closure()
Compile run:
$ swiftc main.swift $ ./main In swift
Test Swift can also use the playground or REPL (read-eval-print-loop) environment directly.
3. A lambda expression for C + +.
#include <iostream>int main(){ auto lambda = []() -> void{ std::cout << "In lambda" << std::endl; }; lambda(); return 0;}
Compile the Run and note the compilation using the features of C + + 11:
$ clang++ main.cpp -std=c++11$ ./a.out In lambda
LAMBDA, block is actually a closure (closure), they are similar to an anonymous function, but have the ability to capture the variables in the scope, can be used as an object function. They are often used to implement functions such as callback functions, proxies, and so on.
How to use lambda
1. Basic form
Grammar |
Serial Number |
[ 捕获列表 ] ( 形参数列表 ) mutable(可选) 异常属性 -> 返回值类型 { 函数体 } |
(1) |
[ capture-list ] ( params ) -> ret { body } |
(2) |
[ capture-list ] ( params ) { body } |
(3) |
[ capture-list ] { body } |
(4) |
- (1) is a complete form that includes a variable capture list, a parameter list, a variable attribute (optional), and a return value type.
- (2) The mutable is omitted, indicating that the lambda cannot modify the captured variable.
- The return value type of a lambda can be omitted if it can be inferred from the actual return value in the body of the function.
- If you do not have formal parameters, you can omit parentheses.
2. Capture List
A lambda expression can get (capture) The value of a variable in its scope, and there are two ways to capture it: a reference and a value. We can set how each variable is captured in the capture list. If you do not set a capture list, Lambda does not capture any variables by default, which is different from block.
#include <iostream>int main(){ int a = 123; Auto Lambda = [] ()void{ std::cout << "in Lambda : " << a << std::Endl; }; Lambda(); return 0;}
Compile run:
$ clang++ main.cpp -std=c++11main.cpp:8:33: error: variable ‘a‘ cannot be implicitly captured in a lambda with no capture-default specified std::cout << "In lambda: " << a << std::endl; ^main.cpp:5:6: note: ‘a‘ declared here int a = 123; ^main.cpp:7:16: note: lambda expression begins here auto lambda = []()->void{ ^1 error generated.
[]
by setting the Capture list in, you can use variables in your lambda a
, which is captured by value (, by value =
).
#include <iostream>int main () {int a = 123auto lambda = [= () ->void{std:: cout << << a << std::endl }; lambda (); return 0;}
Compile run:
$ clang++ main.cpp -std=c++11$ ./a.out In lambda: 123
How the Capture list is set up:
| setting Way | results | |-|-| | []| does not capture | | [=]| All by value Capture | | [&]| All by reference capture | | [A, b]| capture variables A and b| by value | [&a, b]| captures a by reference, captures b| by value | [&, a]| captures a by value, all other variables are captured by reference | | [=, &a]| captures a by reference, all others are captured by value |
Note: The capture list has no precedence, and the variables in the capture list cannot be duplicated, such as the [&, &a]
&
declarations already contained in &a
, and therefore no longer appear &a
.
The specific capture type can be viewed by printing the variable address.
auto lambda = [=]()->void{ std::cout << "In lambda: " << &a << std::endl;};
The result of the operation is:
$ clang++ main.cpp -std=c++11$ ./a.out 0x7fff555c69b8In lambda: 0x7fff555c69b0
auto lambda = [&]()->void{ std::cout << "In lambda: " << &a << std::endl;};
The result of the operation is:
$ clang++ main.cpp -std=c++11$ ./a.out 0x7fff58a9b9b8In lambda: 0x7fff58a9b9b8
3. Variable type (mutable)
The variables passed to the lambda by value are immutable by default (immutable), and if you need to modify them in a lambda, you need to add keywords after the parameter list mutable
(the value passed by value cannot change the values of the lambda variables).
#include <iostream>IntMain(){IntA=123;Std::cout<<A<<Std::Endl;AutoLambda=[=]()mutable->void{a = std::cout << "in Lambda:" Span class= "o" ><< a << std:: endl}; lambda (); std::cout << a << std::endlreturn 0;}
The results of the compilation run are:
$ clang++ main.cpp -std=c++11lishan:c_study apple$ ./a.out 123In lambda: 234 #可以修改123 #注意这里的值,并没有改变
If not added mutable
, the compilation error occurs:
$ clang++ main.cpp -std=c++11main.cpp:9:5: error: cannot assign to a variable captured by copy in a non-mutable lambda a = 234; ~ ^1 error generated.
4. return value type.
The return value type of a lambda can be omitted, and the compiler will automatically derive based on the type of the actual return value.
#include <iostream>IntMain(){IntA=123;Std::cout<<A<<Std::Endl;AutoLambda=[=]()mutable{A=234std::cout << "in Lambda:" Span class= "o" ><< a << std:: endlreturn a}; int b = lambda (); std::cout << b << std::endlreturn 0;}
Compile run:
$ clang++ main.cpp -std=c++11$ ./a.out 123In lambda: 234234
Resources
- Https://msdn.microsoft.com/en-us/library/dd293603.aspx
- Http://www.oracle.com/technetwork/articles/servers-storage-dev/howto-use-lambda-exp-cpp11-2189895.html
- Http://en.cppreference.com/w/cpp/language/lambda
- Http://www.cprogramming.com/c++11/c++11-lambda-closures.html
This document is organized by the Changsha Camp David Education.
C + + Tutorial lambda expression one