c++之—— lambda表达式(有个未能解决的问题等待大佬解答)——(在stack overflow找到了答案)

谓词:

谓词是一个可调用的表达式,其返回结果是一个能用作条件的值。标准库算法所使用的谓词分为两类:一元谓词,意味着它只接受单一参数;二元谓词,意味着它有两个参数。接受谓词参数的算法对输入序列中的元素调用谓词,因此,元素类型必须能转化为谓词的参数类型。典型例子如sort排序算法。

有时候,我们需要更多参数,超出了算法对谓词的限制。如果在编写划分序列的谓词时,可以不必为每个可能的大小都编写一个独立的谓词,显然更有实际价值。

我们可以向一个算法传递任何类别的可调用对象。对于一个对象或一个表达式,如果可以对其使用调用运算符,则称它为可调用的。到目前为止,我们使用过的仅有的两种可带哦用对象时函数和函数指针。还有其他两种可调用对象:重载了函数调用运算符的类以及lambda表达式。

与任何函数类似,一个lambda具有返回类型、参数列表和函数体。但与函数不同,lambda可能定义在函数内部。一个lambda表达式具有如下形式:

[capture list](parameter list) -> return type {fuction body}

capture list(捕获列表)是一个lambda所在函数中定义的局部变量的列表(通常为空)。与普通函数不同,lambda必须使用尾置返回来指定返回类型。

{

尾置返回类型:尾置返回类型跟在形参列表后面并以一个 -> 开头,为了表示函数真正的返回类型跟在形参列表之后,我们在本应该出现返回类型的地方放置一个auto,任何函数的定义都能使用尾置返回。

eg:

int (*func(int i) [10]);这是常见的声明,用尾置返回表示为:

auto func(int i) -> int(*)[10];

回到lambda表达式:

我们可以忽略参数列表和返回类型,但必须包含捕获列表的函数体:

auto f=[] {return 0;}

此例中,我们定义了一个可调用对象f,它不接受参数,返回0。lambda的调用方式与普通函数的调用方式相同,都是使用调用运算符:cout<<f()<<endl;打印0。在lambda中忽略括号和参数列表等价于指定一个空参数列表。在此例中,当调用f时,参数列表是空的。如果忽略返回类型,lambda根据函数体中的代码推断出返回类型。如果函数体只是一个return语句,则返回类型从返回的表达式的类型推断而来。否则,返回类型为void。

当然,lambda也可以有参数,但是与普通函数不同,lambda不能有默认参数,一个lambda调用的实参数目永远与形参数目相等。

 1 #include<iostream>
 2 using namespace std;
 3 
 4 int main()
 5 {
 6     auto f= [] (int a,int b){return a+b; };
 7     cout << f(1,9) << endl;
 8 
 9     return 0;
10 }

使用捕获列表:

虽然一个lambda可以出现在一个函数中,使用其局部变量,但它只能使用那些明确指明的变量。一个lambda通过局部变量包含在其捕获列表中来指出将会使用这些变量。捕获列表指引lambda在其内部包含访问局部变量所需的信息。

eg:

 1 #include<iostream>
 2 using namespace std;
 3 
 4 int main()
 5 {
 6     int a = 3;
 7     auto f= [a] (int ma){return a>ma; };
 8     cout << f(9) << endl;
 9 
10     return 0;
11 }

但是,我遇到一个没有解决的问题,希望有知道的能够解答一下,万分感激。

代码如下:

{/*希望有人解答一下*/

也就是捕获的局部变量名和lambda的形参名一样,怎么区分呢?

我想它的形参的作用域内a是独立于外部局部变量a的,想知道有没有类似this一样的东西区分,因为这样的话我就必须要保证变量名不同。

}

 /*3.23 update*/

http://stackoverflow.com/questions/42088015/lambda-capture-and-parameter-with-same-name-who-shadows-the-other-clang-vs-g

这篇帖子解决了我的问题,还是思考地不够深入,实际上是无名类重载调用运算符,那么参数a顺理成章隐藏捕获的a,由于捕获的是局部变量,所以不能通过域作用符去访问了,但是全局变量还可以,但lambda就是捕获局部变量的,因此,要捕获,请让lambda参数名和捕获名不同。

原文地址:https://www.cnblogs.com/yangguang-it/p/6599307.html