简介
之前在看SICP《计算机程序的构造和解释》一书的时候,中用了大量的Scheme语言(一种Lisp语言的方言)来解释书中的函数式程序设计思想(只读到第二章后半部。。。有空再补)。Scheme的一个主要特性是可以像操作数据一样操作函数调用,
例如实现对一个操作生成的数乘以二的函数:
;这是一个实现对某个值进行乘方的函数
(define square (lambda (x) (* x x)))
;这是我们要实现的函数,其中参数op指的是某个操作
(define double_op (lambda (op x) (* 2 (op x))))
;将square函数作为参数传入double_op函数
(display (double_op square 2))
其中函数可以作为参数参与运算,就像C系语言中的数据一样操作。
“函数是一等公民”,这便是函数式编程的信条,C++11中也开始加入了这一思想:lambda表达式;
语法
C++中 lambda表达式的语法形式如下:
[ captures list] ( params ) -> ret { body }
翻译:
[ 捕获列表 ] ( 参数列表 ) ->( 返回值类型){ 函数体 }
其中参数列表和返回类型是可以省略的
示例
不带参数的lambda表达式
auto f = []{return 42;};
这里就定义了一个返回42的函数, f 则是一个可调用函数对象。
带参数的lambda表达式
[](int a, int b){return a > b;};
我们以往调用标准模板库的排序函数的时候通常是这样的:
//先定义一个比较大小的函数
bool compare(int a,int b)
{
return a<b; //升序排列,如果改为return a>b,则为降序
}
int main()
{
int a[20]={2,4,1,73,1,226,0,43,24,6};
//在sort中再调用compare
sort(a,a+20,compare);
return 0;
}
我们用我们的匿名函数的话,就可以这样写:
int main()
{
int a[20]={2,4,1,73,1,226,0,43,24,6};
//直接写入lambda表达式
sort(a,a+20,[](int a, int b){return a > b;};);
return 0;
}
代码简洁性和美观都秒杀前者,嘿嘿。
带值捕获的lambda表达式
有的时候我们在lambda表达式中需要调用外部数据,这时候就可以将值传入值捕获列表中。
例如写一个返回外部变量a的lambda表达式
int a = 3;
auto f = [a]{return a;};
注意一点,lambda表达式可以捕获引用。
指定返回类型的lambda表达式
到此为止我们举例的lambda表达式都只有一个return语句,假如有多分支的返回语句,则lambda表达式必须指定类型,例如一个判定是否为正数的匿名函数:
int a = 1;
auto f = [](int a)->bool{
if(a > 0)
return true;
else
return false;
};
cout << f(a) << endl;
以上为C++11的lambda基本规则,虽然比不上函数式语言的灵活性,但是在编程方法上给人了新的可能,期待以后C++对函数式编程支持的新特性。