lambda 相当于一个函数,其形式多变,但都是由若干部分组成:
[captures](params)->T{body}
其中 captures
填捕获的方式,params
填传入的参数,T
填返回值类型,body
就是函数主体。
captures
有两种填法:&
和=
,不填时,局部的 lambda 将不会进行捕获,全局的 lambda 默认为&
。
&
表示这个表达式捕获的内容是引用的形式,而 =
表示捕获的内容是复制且只读的
int x=1;
[=](){x=2;}();//CE,向只读变量‘x’赋值
[&](){x=2;}();//OK,x will be 2
//上面 lambda 最后的括号是对其进行调用
这里有坑:请尽量使用 &
,考虑如下程序片段:
vector<int>v(n),o(n);
for(int&x:v)cin>>x;
iota(o.begin(),o.end(),0);
sort(o.begin(),o.end(),[=](int x,int y){return v[x]<v[y];});
其作用是按 v 的大小对其下标 o 排序,但注意使用的是 =
,这意味着每次调用 lambda 时都将 v 拷贝了一份,一共拷贝 nlogn次,直接 TLE。
params
和普通函数一样。
T
若此处省略,则其返回值将为auto
:
[](int x){return x*2.0;}(3);//will return double 6.0
也可使用 auto
将 lambda 表达式作为一个可调用的函数:
auto sqr=[](double x){
return x*x;
};
那么每次调用 sqr(r)
都将返回 r×r的值。
这样写的函数将自带 inline
,比写 inline
短多了。