没有合适的资源?快使用搜索试试~ 我知道了~
小喵的唠叨话: 寒假之后,小喵在家里无所事事,最近用C++写代码的时候,用到了std::sort这个函数,每次用这个函数,小喵似乎都得查一下lambda表达式的写法。正好最近很闲,不如总结一下。 在Bing上搜索 C++ lambda ,第一条记录就是MSDN上的C++ lambda的介绍。本文也是基于这篇文章来写的。 那么接下来,我们分几个部分来介绍。 一、什么是Lambda表达式 MSDN上对lambda表达式的解释: 在 C++ 11 中,lambda 表达式(通常称为 “lambda”)是一种在被调用的位置或作为参数传递给函数的位置定义匿名函数对象的简便方法。 Lambda 通常用于封
资源推荐
资源详情
资源评论
C++ 中的中的Lambda表达式写法表达式写法
小喵的唠叨话小喵的唠叨话:
寒假之后,小喵在家里无所事事,最近用C++写代码的时候,用到了std::sort这个函数,每次用这个函数,小喵似乎都得查一
下lambda表达式的写法。正好最近很闲,不如总结一下。
在Bing上搜索 C++ lambda ,第一条记录就是MSDN上的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表达式整体可以被当做函数的参数或者返回值。
闭包和currying的例子就是将整个lambda表达式作为返回值。现在再举一个作为参数的例子:
#include <iostream>
#include <functional>
int operate(int x, int y, const std::function<int(int, int)> &op) {
return op(x, y);
剩余7页未读,继续阅读
资源评论
weixin_38579899
- 粉丝: 2
- 资源: 979
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功