Lambda表达式起源于函数式编程语言,后来逐渐被面向对象的编程语言所采纳。本文所讨论的不是Lamda表达式的使用方法,而是通过对比Lamda表达式在C#和C++0x中的不同实现而找出其中的区别。
基本的语法结构是()=>{}; 其中()是参数列表部分,用来定义函数的输入参数。定义参数时,用户并不需要定义参数的类型,编译器会根据函数体来“推演”参数的类型。=>部分读作goes to, 意思是函数有如下的函数体。{}部分便是函数的主体部分。一个求2个整数和的例子如下:
(a, b) => a + b;
当函数体只有一条语句的时候,{}符号和return关键字可以省略。
在Lambda函数体中,除了Lamda函数所定义的参数可以被使用外,Lamda函数体还可以使用外部变量,如下例:
void HostingFunction() { int c = 1; Func<int, int, int> f = (a, b) => a + b + c; }
注意被Lamda表达式所捕获的变量是与Lamda表达式是同步的,也就是说任何对原变量值的修改都会影响到Lamda表达式本身,即使对原变量值的修改发生在Lamda表达式生成之后。
基本语法结构是[](){}; 其中[]是变量捕获列表,用来声明需要捕获的外部变量;()是参数列表部分,其功能等同于C# Lamda对应部分;{}是函数体部分,其功能等同于C#Lamda对应部分。一个简单的求2个整数和的例子如下:
[](int a, int b){ return a + b; };
可以看出,不同于C#的声明,C++0x Lamda表达式的参数列表中参数需要声明类型;函数体不能省略{}符号和return关键字;即使单条语句时也不能省略。
C++0x Lamda需要显式声明需要捕获的外部变量,如下例所示:
void HostingFunction() { int c = 1; auto f = [c](int a, int b){ return a + b + c; }; }
代码中声明了需要捕获外部变量c,则函数体中即可引用变量c,否则不能引用。不同于C# Lamda表达式,上述例子中对变量c的改变并不能影响f的行为,因为捕获的c是以值类型捕获的,也即是一份拷贝。如果对变量c采取按引用的方式捕获,则变量c的改变会影响f的行为。如下例:
void HostingFunction() { int c = 1; auto f = [&c](int a, int b){ return a + b + c; }; }
通过对二者的简要对比可得如下几点结论:
来自lsp:http://www.cnblogs.com/lsp/archive/2011/06/24/2088550.html