C++11新特性(3)lambda表达式(1)


C++11新特性(3)lambda表达式(1)

C++11添加了一项名为lambda表达式的新功能.通过这项功能能编写内嵌的匿名函数,而不必编写独立函数或函数对象,使得代码更加理解.
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表达式进行代码重用了!
对lambda的基本介绍就到这里了,更深入的内容请看下一章.


发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注