lambda匿名函数

  lambda函数是C++11标准中最人激动的特性之一,因为它们可以极大地简化代码,以及大量消除与编写可调用对象相关的样板。C++11 lambda 函数语法允许一个函数在另一个表达式中需要它的地方进行定义。这对于有些东西非常有用,如提供给等待函数conditi_variable的断言,因为它允许予以可以访问的变量的形式快速被表达式,而不是通过调用函数来实现。

一个最简答lambda表达式定义一个不接受参数,只依赖于全局变量和函数自包含函数,甚至不必返回值。这样的lambda表达式就是包括在一对花括号的一系列语句,之前缀以方括号

[]->bool        ---显示指定返回值
{
do_stuff();
do_more_stuff();
}

使用[]作为lambda引导符的lambda函数不能引用任何包含它作用域的局部变量,它们只能使用全局变量和参数传入的东西。如果你希望访问某个局部变量你需要捕获它。最简单的做法就是通过使用[=]作为lambda引导符,来捕获局部作用域中的整个变量集。但是你的lambda被其创建的时候访问局部变量的副本。还有一种访问是通过引用来捕获但是一旦lambda所引用的变量因为离开其所在的函数或语句块作用域而被消耗,那调用lambda则就成为了一个未定的行为。

function<int(int)> make_offseter(int offset)
{
return [=] (int j){return offset + j;};  //返回lambda
}

其实C++之所以称为C++,你并不会受困于这些非黑即白的选项(要么就是1要么就0),你可以选择捕获复制一部分,引用一部分。

int main()
{
int i = 1234,j=5678,k = 9;
function<int()> f= [=,&j,&k] {return i + j + k;};
i = 1;
j = 2;
k = 3;
cout<<f()<<endl;
}
//答案是 1239

另外,你可以默认引用捕获,但是通过复制捕获变量的一个指定子集。在这种情况下,使用lambda引用符的[&]形式,但在&好后面跟以复制捕获的列表。

int main()
{
   int i = 1234,j = 5678,k = 9;
   function<int()> f = [&,j,k]{return i + j+k;};
   i = 1;
   j = 2;
   k = 3;
   return 0;
}
//答案是 5688

类成员不能被直接捕获,如果你希望从lambda中访问类成员,你必须将this指针添加到捕获列表中先行捕获。

struct X
{
int some_data
void foo(vector<int> &a)
{
for_eat(a.begin(),a.end,[this](int & i)
{
i +=  some_data; //他可以访问some_data
});

}

}

 

posted @ 2020-03-16 15:23  Detach  阅读(168)  评论(0)    收藏  举报