—-想了解C++ 中的Lambda表达式写法分享的全部内容且更多的C语言教程关注<计算机技术网(www.ctvol.com)!!>
小喵的唠叨话:
寒假之后,小喵在家里无所事事,最近用C++写代码的时候,用到了std::sort这个函数,每次用这个函数,小喵似乎都得查一下lambda表达式的写法。正好最近很闲,不如总结一下。
在Bing上搜索 C++ lambda ,第一条记录就是MSDN上的C++ lambda的介绍。C++ 中的Lambda表达式写法分享也是基于这篇文章来写的。
那么接下来,我们分几个部分来介绍。
一、什么是Lambda表达式
MSDN上对lambda表达式的解释:
在 C++ 11 中,lambda 表达式(通常称为 “lambda”)是一种在被调用的位置或作为参数传递给函数的位置定义匿名函数对象的简便方法。 Lambda 通常用于封装传递给算法或异步方法的少量代码行。 [1]
看了这个解释,相信大家已经理解lambda表达式是什么。简而言之,lambda表达式就是一种定义函数的简单的方法。
举一个简单的例子:求一个数的阶乘。
这是一般的函数的写法:
// 这里要求n>=0,同时n的取值不能太大,会溢出 // 为了方便,这里并没有处理上面说到的问题 int factorial(int n) { int fact = 1; for (int i = 1; i <= n; ++ i) fact *= i; return fact; }
Lambda表达式的写法:
autofactorial = [](int n) { int fact = 1; for (int i = 1; i <= n; ++ i) fact *= i; return fact; };
乍一看,这两种定义方式十分的相似。但其实这是两种完全不同的方式,前一种是函数定义式,而后一种是一个表达式。factorial是变量名,等于号后面的是值,也就是一个lambda表达式,本质上是一个匿名的函数。最终factorial就是一个函数。
很多时候,我们只是直接书写lambda表达式,而不需要给他一个免费精选名字大全。比如排序的时候,sort可以接受一个自定义的比较函数,这时候直接书写lambda表达式即可。
二、Lambda表达式的作用
由于lambda本身其实也就是一种函数的定义方式。因此它的主要作用还是和一般函数一样。但是lambda表达式相对于一般函数,又有一些功能之外的作用。参考了知乎上的一些回答 [2] ,小喵也进行了总结。
1、可以用表达式来定义函数,这样使得函数的定义和调用在一起,语意和逻辑上更为紧凑。同时,对于只是用一次的短小的函数,直接调用匿名的lambda表达式是最好的选择,这样就不需要给每个函数起免费精选名字大全了。 /* 起免费精选名字大全一直是一个很令人头疼的问题 */
2、闭包(Closure)。这个小喵的写javascript的时候时常会用到。闭包本质上就是能够访问上下文环境中变量的代码块。
这里我们简单的举个例子,还是之前的求阶乘的问题,现在我们有些提高需求。
现在需要完成下面的三种阶乘的运算:
n! = n * (n – 1) * (n – 2) * …
n!! = n * (n – 2) * (n – 4) * …
n!!! = n * (n – 3) * (n – 6) * …
要求编写3个函数,分别完成上述3种计算。
使用一般的方式写很容易实现,我们这里直接使用lambda表达式来实现:
#include <iostream> #include <functional> std::function<int(int)> getFactorialFunc(int n) { return [n](int x) { int fact = 1; for (; x >= 1; x -= n) fact *= x; return fact; }; } int main() { // 构造要求的三个函数 autofactorial1 = getFactorialFunc(1); autofactorial2 = getFactorialFunc(2); autofactorial3 = getFactorialFunc(3); // 调用 std::cout << factorial1(10) << std::endl; std::cout << factorial2(10) << std::endl; std::cout << factorial3(10) << std::endl; }
编译的时候要注意,lambda表达式是C++11开始支持的,所以需要指定一下C++的版本。
g++ factorial_lambda.cpp -o factorial_lambda.out --std=c++11
运行之后的结果为:
./factorial_lambda.out
3628800
3840
280
这里作为返回值的lambda表达式,可以访问先前传入的参数,这也就是闭包。具体的语法,我们后面会讲到。
3、柯里化(Currying)。这部分小喵也是第一次接触,维基百科有如下解释:
在计算机科学中,柯里化(英语:Currying),又译为卡瑞化或加里化,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。 [3]
下面给出一个例子(也是实现之前的阶乘):
#include <iostream> #include <functional> // 两个参数的阶乘 int factorial(int n, int step) { int r = 1; for (; n >= 1; n -= step) { r *= n; } return r; } // curring化的阶乘 std::function<int(int)> currying_factorial(int step) { return [step](int n) { return factorial(n, step); }; } int main() { // 调用普通函数 std::cout << factorial(10, 1) << std::endl; std::cout << factorial(10, 2) << std::endl; std::cout << factorial(10, 3) << std::endl; // 调用currying函数 std::cout << currying_factorial(1)(10) << std::endl; std::cout << currying_factorial(2)(10) << std::endl; std::cout << currying_factorial(3)(10) << std::endl; return 0; }
4、lambda表达式整体可以被当做函数的参数或者返回值。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/487789.html