文章目录
- 定义
- 捕捉列表的形式
- 一些更复杂的捕捉列表组合
- 代码演示
- 演示一
- 演示二
- 演示三
- 演示四
- 演示五
- 演示六
lambda 函数,是C++11中新引入的函数式编程语法,lambda函数可以被定义在类中成员函数内部,全局函数的内部。它是一个局部函数(即在函数作用域中定义的函数)。
一般都是定义在函数的内部,底层编译器会把lambda函数编译为仿函数。
定义
lambda函数的语法定义如下:
[capture](parameters) mutable ->retrun-type{statement};
[capture]
:捕捉列表。捕捉列表总是出现在lambda函数的开始处。事实上,[]是lambda引出符。编译器根据该引出符判断接下来的代码是否是lambda函数。捕捉列表能够捕捉上下文中的变量以供lambda函数使用。
(parameters)
:参数列表。与普通函数的参数列表一致。如果不需要参数传递,则可以连同括号()一起省略。
mutable
: mutable 修饰符。默认情况下。lambda函数总是一个const函数,mutable可以取消其常量性。
在使用该修饰符时,参数列表不可以省略(即使参数为空)。
->retrun-type
: 返回类型。用追踪返回类型形式声明函数的返回类型。
出于方便,不需要返回值的时候也可以连同符号->一起省略。此外,在返回类型明确的情况下,
也可以省略该部分,让编译器对返回类型进行推导。例如: ->void ; ->int ; ->bool
->retrun-type 是一个整体要省略时都省略。例如:[]->{} //是错误写法
{statement}
: 函数体。内容与普通函数一样,不过除了可以使用参数以外,还可以使用所有捕获的变量。
在极端情况下,C++11中最为简略的lambda函数只需要声明为 []{};但是该lambda函数不能做任何事情。
捕捉列表的形式
语法上 捕捉列表由多个捕捉项组成,并以逗号分割。捕捉列表有如下几个形式:
[var]
表示值传递方式捕捉变量var。这是方式变量var,必须是父作用域内的自动变量,捕捉任何非此作用域或者是非自动变量都会编译报错。
[=]
表示值传递方式捕捉所有父作用域及全局作用域的变量(包括this)。
[&var]
表示引用传递方式捕捉变量var。这是方式变量var,必须是父作用域内的自动变量,捕捉任何非此作用域或者是非自动变量都会编译报错。
[&]
表示引用传递方式捕捉所有父作用域及全局作用域的变量(包括this)。
[this]
表示值传递方式捕捉当前的this指针。
注意:
父作用域:这里指的是包含lambda函数的语句块。
一些更复杂的捕捉列表组合
[c,&a,&b]
: 表示以引用传递方式捕捉变量a和b,值传递方式捕捉变量c。
[=,&a,&b]
: 表示以引用传递方式捕捉变量a和b,值传递方式捕捉其他所有变量。
[&,a,this]
: 表示以值传递方式捕捉变量a和this,引用传递方式捕捉其他所有变量。
不过值得注意的是,捕捉列表不允许变量重复传递。否则会导致编译时期报错。
[=,a]
这里=已经以值传递方式捕捉了所有变量,再捕捉a重复。
[&,&this]
这里&已经以引用传递方式捕捉了所有变量,再捕捉this重复。
代码演示
演示一
int main(int argc, char* argvs[])
{
int girls = 3, boys = 6;
//定义一个lambda函数
auto totalChilds = [=]() mutable ->int
{
int total = girls + boys;
cout << __func__ << ": total= " << total << endl;
return total;
};
cout << __func__ << ": totalChilds= " << totalChilds() << endl;
}
注意:
这里使用了一个auto关键字推导出了totalChilds变量的类型为匿名lambda函数,后续就可以再父函数内使用totalChilds来调用lambda函数使用了。
通过__func__ 打印输出可以看到在lambda函数内会被打印处operator()。即仿函数的名称。说明了lambda函数也是一种仿函数。
演示二
int main(int argc, char* argvs[])
{
int girls = 3, boys = 6;
auto totalChilds = [=](int a) mutable ->int
{
int total = girls + boys + a;
cout << __func__ << ": total= " << total << endl;
return total;
};
cout << __func__ << ": totalChilds= " << totalChilds(5) << endl;
}
注意:
totalChilds中传递的数值5会被传递给lambda函数的形式参数a。
演示三
int main(int argc, char* argvs[])
{
int girls = 3, boys = 6;
auto totalChilds = [&]() ->int
{
int total = girls + boys;
cout << __func__ << ": total= " << total << endl;
return total;
};
cout << __func__ << ": totalChilds= " << totalChilds() << endl;
}
注意:
没加mutable,默认就是const,即不能在lambda内修改传递进来的变量的值。但是这个const关键字不能显示的写出来,否则编译报
错。
演示四
int main(int argc, char* argvs[])
{
int girls = 3, boys = 6;
auto totalChilds = [girls, boys]() ->int
{
int total = girls + boys;
cout << __func__ << ": total= " << total << endl;
return total;
};
cout << __func__ << ": totalChilds= " << totalChilds() << endl;
}
演示五
int main(int argc, char* argvs[])
{
int girls = 3, boys = 6;
auto totalChilds = [&girls, &boys]() ->int
{
int total = girls + boys;
cout << __func__ << ": total= " << total << endl;
return total;
};
cout << __func__ << ": totalChilds= " << totalChilds() << endl;
}
演示六
int main(int argc, char* argvs[])
{
int girls = 3, boys = 6;
auto totalChilds = [girls, boys]()
{
int total = girls + boys;
cout << __func__ << ": total= " << total << endl;
//return total;
};
totalChilds(); //无返回值
}