Lambda函数是C++ 11中引入的现代C++的一个直观概念。使用lambda表达式可编写内嵌的匿名函数。而不必编写独立函数或函数对象,使代码更容易阅读和理解。
Lambda语法
lambda表达式以方括号[]开始(这称为lambda引入符),其后是花括号{},其中包含lambda表达式体。lambda表达式被赋予自动类型变量basicLambda。第二行使用普通的函数调用语法执行lambda表达式。
auto basicLambda = [ ] { cout << "Hello from Lambda" << endl; };
basicLambda();
输出如下所示:
Hello from Lambda
lambda表达式可以接收参数。参数在圆括号中指定,用逗号隔开,与普通函数相同。下面是使用参数的示例:
auto parameterLambda =
[ ] (int value) { cout << "The value is " << value << endl; };
parameterLambda (42);
如果lambda表达式不接收函数,就可指定空圆括号或忽略它们。
lambda表达式可返回值。返回类型在箭头后面指定,称为拖尾返回类型。下例定义的lambda表达式接收两个参数,返回它们的和:
auto returningLambda = [ ] (int a, int b) -> int {return a + b; };
int sum = returningLambda(11, 22);
Capture(用以访问外部作用域)
在lambda introducer (每个lambda最开始的方括号)内,你可以指定一个capture用来处理外部作用域内未被传递为实参的数据:
- [=] 意味着外部作用域以by value方式传递给lambda。
- [&] 意味着外部作用域以by reference方式传递给lambda。
#include <iostream>
#include <string>
int main()
{
int x=0;
int y=42;
auto qqq = [x, &y] {
std::cout << "x: " << x << std::endl;
std::cout << "y: " << y << std::endl;
++y;
//++x; Not Ok
};
x = y = 77;
qqq();
qqq();
std::cout << "final x: " << x << std::endl;
std::cout << "final y: " << y << std::endl;
return 0;
}
会产生以下输出:
kent@ubuntu:~/source/lambda$ ./a.out
x: 0
y: 77
x: 0
y: 78
final x: 77
final y: 79
由于x是因by value而获得一份拷贝,在此labmda内部你可以改动它,但若调用++x是通不过编译的。y以by reference方式传递,所以你可以涂写它,并且其值的变化会影响外部;所以调用这个labmda二次,会使指定值77被累加。
kent@ubuntu:~/source/lambda$ g++ lambda.cpp
lambda.cpp: In lambda function:
lambda.cpp:12:5: error: increment of read-only variable ‘x’
++x;
^
你也可以写[=, &y]取代[x, &y],意思是以by reference方式传递y,其他所有实参则以by value方式传递。
为了获得passing by value和passing by reference混合体,你可以声明labmda为mutable。下例中的对象都以by value方式传递。但在这个lambda所定义的函数对象内,你有权力涂写传入的值。例如:
#include <iostream>
#include <string>
int main()
{
int id=0;
auto f = [id] () mutable {
std::cout << "id: " << id << std::endl;
++id; //OK
};
id = 42;
f();
f();
f();
std::cout << "id: " << id << std::endl;
return 0;
}
会产生以下输出:
kent@ubuntu:~/source/lambda$ ./a.out
id: 0
id: 1
id: 2
id: 42