1 Lambda结构
Lambda是C++11中新增的机制,它其实就是匿名函数,任何可以在用函数指针或者函数对象的地方就可以用Lambda表达式,它的结构如下所示
[](parameter)mutable throw() -> Type{
//body
}
[] 是capture列表,parameter是函数参数,mutable让传值的捕捉能够改变其值,throw()是抛出异常,->Type是函数返回值,{}是函数体
2 关于capture
首先capture 可以有3种情况 default, list, default + list,下面一一介绍
《1》default
它表达的是捕捉列表中所有对象的默认传递情况
有[&],[=]两种形式,[&] 表示所有的变量都是以引用传递,那么所有变量都可以在{}中被修改,并且调用结束后,修改被保存下来。
[=]表示所有的变量都是传值调用,并且默认情况下传值调用的变量在{}中不能被修改,如果要修改,则必须在在Lambda中添加mutable关键字。
《2》list
就是把所有变量一个一个加入到列表中,加入的方式可以有传引用方式,传值方式,或者混合,如下所示:
[x,y],[&x,&y],[&x,y]
list中一种特殊情况就是[],他表示不传递任何变量,所以在{}中不能用任何外围的变量
《3》default + list
这个就是整体加局部的思想的体现,default 指定了全体变量的传递方式,但是如果个别变量跟大部队不一样,就需要在list中指出来了,如;
[&, x]-->x是传值调用,y是传引用
[=,&y]-->x是传值调用,y是传引用
3 关于parameter
parameter 跟 一般函数的参数类似,但是有三点除外,
不能有默认参数;
不能有可变参数列表;
不能有没有名字的参数;
当参数为空的时候,参数可以被省略,如下所示:
int z = [=] { return x + y; }();
4 关于mutable
它指定了传值调用的捕捉变量是否能被修改,有mutable则可以,反之则不
5 throw()
有它时候,不会抛出异常,如果此时在{}抛出异常,那么vs编译器产生了一个警告。
6 返回值
->Type 指定了函数的返回值,可以省略,编译器会根据函数的return返回值,自动推断返回值,如果return语句,则推断为void
7 函数体
函数体类似一般的函数体,它可以访问的变量有下面几种
1 自己局部声明的
2 参数列表中的
3 静态存储变量
4 类中的成员
5 捕捉列表中的变量
关于类中的成员变量有个小demo;
Lambda是C++11中新增的机制,它其实就是匿名函数,任何可以在用函数指针或者函数对象的地方就可以用Lambda表达式,它的结构如下所示
[](parameter)mutable throw() -> Type{
//body
}
[] 是capture列表,parameter是函数参数,mutable让传值的捕捉能够改变其值,throw()是抛出异常,->Type是函数返回值,{}是函数体
2 关于capture
首先capture 可以有3种情况 default, list, default + list,下面一一介绍
《1》default
它表达的是捕捉列表中所有对象的默认传递情况
有[&],[=]两种形式,[&] 表示所有的变量都是以引用传递,那么所有变量都可以在{}中被修改,并且调用结束后,修改被保存下来。
[=]表示所有的变量都是传值调用,并且默认情况下传值调用的变量在{}中不能被修改,如果要修改,则必须在在Lambda中添加mutable关键字。
《2》list
就是把所有变量一个一个加入到列表中,加入的方式可以有传引用方式,传值方式,或者混合,如下所示:
[x,y],[&x,&y],[&x,y]
list中一种特殊情况就是[],他表示不传递任何变量,所以在{}中不能用任何外围的变量
《3》default + list
这个就是整体加局部的思想的体现,default 指定了全体变量的传递方式,但是如果个别变量跟大部队不一样,就需要在list中指出来了,如;
[&, x]-->x是传值调用,y是传引用
[=,&y]-->x是传值调用,y是传引用
3 关于parameter
parameter 跟 一般函数的参数类似,但是有三点除外,
不能有默认参数;
不能有可变参数列表;
不能有没有名字的参数;
当参数为空的时候,参数可以被省略,如下所示:
int z = [=] { return x + y; }();
4 关于mutable
它指定了传值调用的捕捉变量是否能被修改,有mutable则可以,反之则不
5 throw()
有它时候,不会抛出异常,如果此时在{}抛出异常,那么vs编译器产生了一个警告。
6 返回值
->Type 指定了函数的返回值,可以省略,编译器会根据函数的return返回值,自动推断返回值,如果return语句,则推断为void
7 函数体
函数体类似一般的函数体,它可以访问的变量有下面几种
1 自己局部声明的
2 参数列表中的
3 静态存储变量
4 类中的成员
5 捕捉列表中的变量
关于类中的成员变量有个小demo;
class A {
public:
A() : m_a(0) {}
A(int x) : m_a(x) {}
void fun()
{
int z = [this]() {
return m_a++;
}();
std::cout << "class func z: " << z << std::endl;
std::cout << "class func ma: " << m_a << std::endl;
}
private:
int m_a;
};
int main()
{
A xx = 5;
xx.fun();
return 0;
}
output:
class func z: 5
class func ma: 6
8 capture测试小demo
int main()
{
int x = 1;
int y = 2;
//1: empty
// error , 无法隐式捕捉x,y,因为没有指定默认捕捉方式
// output, error
//[](int z) {
// x += z;
// y += x;
//}(3);
//2: default &
//ok
//output: 4, 6
//[&](int z) {
// x += z;
// y += x;
//}(3);
//3: default =
//error,无法在非可变lambda中修改,通过复制捕获
//output: error
/*[=](int z) {
x += z;
y += x;
}(3);*/
//4: default =
//ok
//output: 6, 1, 2
/*[=](int z) {
std::cout << x + y + z << std::endl;
}(3);*/
//5: default =
//ok
//output: 1, 2
/*[=](int z) mutable{
x += z;
y += x;
}(3);*/
//6: default & , list
//ok
//output: 4, 2
/*[&, y](int z) mutable {
x += z;
y += x;
}(3);*/
//7: default = , list
//ok
//output: 1, 6
//[=, &y](int z) mutable {
// x += z;
// y += x;
//}(3);
//8: list
//ok
//output: 4, 6
/*[&x, &y](int z) {
x += z;
y += x;
}(3);*/
//9: list
//ok
//output: 1, 2
//[x, y](int z)mutable {
// x += z;
// y += x;
//}(3);
//9: list
//ok
//output: 1, 6
[x, &y](int z)mutable {
x += z;
y += x;
}(3);
std::cout << "x: " << x << std::endl;
std::cout << "y: " << y << std::endl;
return 0;
}