lambda表达式也称之为匿名函数,听起来很神秘,但是这比起那些那些嵌套定义的概念来看,这个真的很简洁了,它几乎没有借用其他任何定义,似乎也没有其它任何借用它的定义。
一个lambda具有一个返回类型、一个参数列表和一个函数体。但与函数不同,lambda可能定义在函数内部。一个lambda表达式具有如下形式
- [capture list](parameter list) -> return type (function body)
与普通函数不同,lambda函数必须使用尾置返回,那什么是尾置返回呢?
尾置返回是C++ 11 出现的一种简化声明的一种方法,有些遗忘了,我翻了下primer C++。
首先回顾一下指针数组和数组指针:
int arr[10];//是一个含有10个整数的数组
int *p1[10];//p1是一个含有10个指针的数组
int (*p2)[10];//p2是一个指向含有10个整数的数组
如果我们想定义一个返回数组指针的函数,则数组的维度必须跟在函数的名字之后。然而,函数的形参列表也跟在函数名字后面且形参列表应该先于数组的维度。因此,返回数组指针的函数形式如下表示:
- Type (*function(parameter list))[dimension]
书上的例子
- int (*func(int i)[10])
表示函数func,含有一个形参int,返回值时一个指向大小是int[10]的指针
这样看起来,定义这种返回值时很麻烦的,所以,索性,C++ 11采取了一种更为简化好理解的方法
它的整体形式如下:
auto func(int i) -> int (*)[10];
尾置返回类型跟在形参列表后面并以一个->开头
读到这里,应该理解了最上面的 -> return type,需要注意的是,这个是可以省略的,lambda函数可以根据自己的return语句来给出自己的返回类型,所以我觉得,一般情况下,不要这个 ->return type,避免不必要的bug
接下来我们再理解一下cpturelist(捕获列表),当我们lambda表达式需要用到所在函数内的一些变量时,就需要利用捕获列表将其捕获下来,如果不需要,可以为空,但是[]不能省略
而parameter list则是可以省略的,并且不能有默认值,这与我们通常用的函数有些区别
写一个最简单的lambda表达式
[](return 1;);
够简洁吧,这个就是省略了参数列表,省略了返回类型,捕获参数列表为空
初学的时候,就很好奇,既然称之为匿名函数,那如何传递参数,没有名字啊,回答我这个疑惑的有两个答案,第一是它其实是有名字的,我们可以做这样的定义:
auto f=[]{return 1;};
然后调用f()就可以了,这样子并没有匿名啊,后来我想到了algorithm里面那些函数,看看for_each的定义吧:
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function fn)
{
while (first!=last) {
fn (*first);
++first;
}
return fn; // or, since C++11: return move(fn);
}
这里的Function fn就可以写成lambda函数,作为形参出现在其它的函数体里面,如果你调用for_each之后,并且在调用的时候写了一个lambda表达式之后,我认为系统给了它一个临时的函数名,然后就可以在执行for_each的时候,像调用普通函数一样调用。
总结一下,所谓lambda函数,就是省略了声明过程,直接写出定义语句,并且把函数名也省略了,然后编译器悄悄给了它一个你不知道的名字,但是你在形参里面还是会选择给它个名字。
又看到了move,接下来写写move的内容吧