到目前为止,我听说:
- λ演算
- Lambda程式设计
- Lambda表达式
- Lambda函数
这似乎都与函数式编程有关...
显然它将被集成到C ++ 1x中,所以我现在可能会更好地理解它:
http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions
有人可以简短地定义什么是lambda事物,并给出一个有用的地方吗?
到目前为止,我听说:
这似乎都与函数式编程有关...
显然它将被集成到C ++ 1x中,所以我现在可能会更好地理解它:
http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions
有人可以简短地定义什么是lambda事物,并给出一个有用的地方吗?
Answers:
λ演算是30年代Alonzo Church发明的一种计算模型。大多数功能性编程语言的语法和语义直接或间接地受到lambda演算的启发。
最基本形式的lambda演算有两个操作:抽象(创建(匿名)函数)和应用(应用函数)。使用λ运算符执行抽象,为lambda微积分取名。
匿名函数通常被称为“ lambdas”,“ lambda函数”或“ lambda表达式”,因为如上所述,λ是在lambda演算中创建匿名函数的符号(该词lambda
在许多lisp中用于创建匿名函数基于相同语言的语言)。
这不是一个常用术语,但是我认为这意味着使用匿名函数进行编程或使用高阶函数进行编程。
有关C ++ 0x中的lambda,它们的动机以及它们与函数指针的关系的更多信息(很多可能是您已经知道的重复,但是我希望它可以帮助解释lambda的动机以及它们之间的区别从函数指针):
函数指针(已存在于C中)对于例如将比较函数传递给排序函数非常有用。但是,它们的用途受到限制:
例如,如果要按i
每个向量的第th个元素对向量进行排序(其中i
是运行时参数),则无法使用函数指针来解决。一个将两个向量按其i
th元素进行比较的函数将需要使用三个参数(i
以及两个向量),但是sorting函数将需要一个使用两个参数的函数。我们需要的是一种在将参数i
传递给排序函数之前以某种方式将其提供给函数的方法,但是我们不能使用普通的C函数来做到这一点。
为了解决这个问题,C ++引入了“功能对象”或“功能部件”的概念。函子基本上是具有operator()
方法的对象。现在,我们可以定义一个类CompareByIthElement
,该类将参数i
作为构造函数参数,然后将要比较的两个向量作为operator()
方法的参数。为了通过i
th元素对向量进行排序,我们现在可以创建一个CompareByIthElement
对象i
作为参数,然后将该对象传递给排序函数。
由于函数对象只是对象,从技术上来说并不是函数(即使它们的行为与它们相同),因此不能使函数指针指向函数对象(当然可以具有指向函数对象的指针,但是它可以将具有类似的类型CompareByIthElement*
,因此不是函数指针)。
C ++标准库中大多数以函数为参数的函数都是使用模板定义的,因此它们可以与函数指针以及函数对象一起使用。
现在到lambdas:
i
如果只用一次它来对向量进行排序,那么用th元素定义要比较的整个类会有点冗长。即使在只需要一个函数指针的情况下,如果仅使用一次,则定义命名函数也是次优的,因为a)它会污染名称空间,b)该函数通常会非常小,并且实际上并没有将逻辑抽象为自己的函数的一个很好的理由(除了没有定义函数就不能拥有函数指针的原因)。
因此,为了解决此问题,引入了lambda。Lambda是函数对象,而不是函数指针。如果使用lambda文字,[x1, x2](y1,y2){bla}
则会生成类似代码的代码,该代码基本上会执行以下操作:
x1
和x2
),一个operator()
具有参数(y1
和y2
)和主体bla
。x1
和x2
对变量的值x1
和x2
当前在范围之内。因此,lambda的行为类似于函数对象,但除了使用lambda之外,您无法以其他任何方式访问为实现lambda而生成的类。因此,任何接受函子作为参数的函数(基本上意味着标准库中的任何非C函数)都将接受lambda,但仅接受函数指针的任何函数均不会接受。
std::sort
例如),您将能够使用匿名函数。但是,在定义应将匿名函数作为其参数的函数时,您需要使用模板或将其std::function
用作参数的类型。
+1
从我。
基本上,lambda函数是您“动态”创建的函数。在C ++ 1x中,它们可以用来改进其对函数式编程的支持:
std::for_each( begin, end, [](int i){std::cout << i << '\n';} );
这将大致导致类似于以下代码:
struct some_functor {
void operator()(int i) {std::cout << i << '\n';}
};
std::for_each( begin, end, some_functor() );
如果some_functor
只需要对的一次调用std::for_each()
,则该lambda函数相对于它有几个优点: