lambda表达式包含以下部分.
[capture_block](parameters) mutable exception_specification->return_type {body}
现在分析各个部分的内容:
(capture_block)捕捉块:指定如何捕捉所在作用域的变量,并供给lambda主体部分使用.
(parameter)参数(可选):lambda表达式使用的参数列表.只有在不需要任何参数并且没有指定mutable,一个exception_specification和一个return_type的情况下可以忽略该列表.任何类型在某些情形下也是可以忽略的.例如:[]{return 10;};
mutable:(可选):如果所在作用域的变量是通过值捕捉的,那么lambda表达式的主体中就不能修改这些副本的值.这些副本默认标记为const,因此lambda表达式主体不能修改这些副本的值.如果lambda表达式标记为mutable,那么这些副本则不是const,因此主体可以修改这些本地副本.(类似于参数传递中的值传递以及引用传递修改源值)
exception_specification:(可选)用于指定lambda表达式可以抛出的异常.
Return_type(可选)返回值的类型:如果忽略了return_type,那么编译器会根据以下原则判断返回类型:
1)如果lambda表达式主体的形式为{return exception;},那么lambda表达式的return_type为exception的类型;
2)其他情况下的return_type为void.
下面看一些例子:
//test2.cpp
#include <iostream>
using namespace std;
int main(){
[]{cout<<"hello lambda!"<<endl;}();
}
看编译以及运行的结果
来剖析一下这个lambda表达式的各部分
[]{cout<<"hello lambda!"<<endl;}();
[]:这是捕捉块,参数为空;
{cout<<"hello lambda!"<<endl;}:这是body
():这是为了让该lambda表达式立即执行.
因为实际上[]{cout<<"hello lambda!"<<endl;}就是lambda表达式的所有组成部分,其功能类似于一个匿名的函数,要让其立即执行,必须调用该函数,而该函数是匿名的,该如何调用呢?
其实[]{cout<<"hello lambda!"<<endl;}就相当于函数的名称了,因为其参数为空,因此只需要传递一个空参即可调用,要验证也是很容易的,例如
#include <iostream>
using namespace std;
int main(){
[](int n){cout<<"hello lambda!+"<<n<<endl;}(10086);
}
可以很容易看出其中的规律!
再看一个复杂一点的拥有返回值的lambda表达式.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string result=[](const string &str)->string{return "this is "+str;}("lambda!");
cout<<result<<endl;
}
string result=[](const string &str)->string{return "this is "+str;}("lambda!");
这个例子里面指明了这个lambda返回值为string!
当然,这个返回值也是可以忽略的,返回值就是"this is "+str的类型,很明显,这是一个string类型.
还可以保存指向lambda表达式的指针,这样就可以很方便的调用该lambda表达式,使用C++11中的auto关键字进行声明.例如:
#include <iostream>
#include <string>
using namespace std;
int main()
{
auto func=[](const string &str){return "this is "+str;};
cout<<func(" one!")<<endl;
cout<<func(" two!")<<endl;
}
对lambda的基本介绍就到这里了,更深入的内容请看下一章.