C++11中的Lambda表达式
本文地址:http://www.cnblogs.com/archimedes/p/c11-lambda.html,转载请注明源地址。
“Lambda 表达式”(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包(注意和数学传统意义上的不同)。
ISO C++ 11 标准的一大亮点是引入Lambda表达式。基本语法如下:
[capture list] (parameter list) ->return type { function body }
其中除了“[ ]”(其中捕获列表可以为空)和“复合语句”(相当于具名函数定义的函数体),其它都是可选的。它的类型是唯一的具有成员operator()的非联合的类类型,称为闭包类型(closure type)。
C++中,一个lambda表达式表示一个可调用的代码单元。我们可以将其理解为一个未命名的内联函数。
它与普通函数不同的是,lambda必须使用尾置返回来指定返回类型。
例如:调用<algorithm>中的std::sort,ISO C++ 98 的写法是要先写一个compare函数:
bool compare(int &a, int &b) {return a > b; //降序排序 }
然后,再这样调用:
sort(a, a + n, compare);
然而,用ISO C++ 11 标准新增的Lambda表达式,可以这么写:
sort(a, a + n, [](int a, int b){return a > b;}); //降序排序
这样一来,代码明显简洁多了。
由于Lambda的类型是唯一的,不能通过类型名来显式声明对应的对象,但可以利用auto关键字和类型推导:
auto f = [](int a, int b){return a > b;});
和其它语言的一个较明显的区别是Lambda和C++的类型系统结合使用,如:
autof = [x](int a, int b){return a > x;});//x被捕获复制 int x = 0,y = 1; auto g = [&](int x){return ++y;});//y被捕获引用,调用g后会修改y,需要注意y的生存期 bool(*fp)(int, int) = [](int a, int b){return a > b;});//不捕获时才可转换为函数指针
Lambda表达式可以嵌套使用。
即将出版的ISO C++14支持基于类型推断的泛型lambda表达式。上面的排序代码可以这样写:
sort(a, a + n, [](const auto &a, const auto &b){return a > b;});//降序排序:不依赖a和b的具体类型
因为参数类型和函数模板参数一样可以被推导而无需和具体参数类型耦合,有利于重构代码;和使用auto声明变量的作用类似,它也允许避免书写过于复杂的参数类型。特别地,不需要显式指出参数类型使使用高阶函数变得更加容易。
下面举一个简单使用Lambda表达式的例子:
#include<iostream> #include<algorithm> #include<vector> #include<ostream> using namespace std; int main() {vector<int> v;for (int i = 0; i < 10; i++){v.push_back(i);}for_each(v.begin(), v.end(), [](int n){cout << n << " "; });cout << endl;return 0; }
Lambda表达式默认的返回类型为void
为了对比,下面使用函数对象实现相同功能的代码:
#include<iostream> #include<algorithm> #include<vector> #include<ostream> #include<cassert> using namespace std;class LambdaFunctor{ public:void operator()(int n) const{cout << n << " ";} };int main() {vector<int> v;for (int i = 0; i < 10; i++){v.push_back(i);}for_each(v.begin(), v.end(), LambdaFunctor());cout << endl;return 0; }
对比一下,就会发现使用Lambda表达式要简洁得多
上面提到的Lambda表达式可以操作所在作用域的变量,这需要通过被称为“捕获”的特殊语法来实现,就是通过在[]内列出将要捕获的“外部”变量列表,这样在函数体内就可以访问并操作这些变量。参考下面的代码:
#include<iostream> #include<algorithm> #include<vector> #include<ostream> #include<cassert> using namespace std;int main() {vector<int> v;for (int i = 0; i < 10; i++){v.push_back(i);}//使用for_each语句和Lambda表达式来实现对偶元素的计数int evenCount = 0;for_each(v.begin(), v.end(), [&evenCount](int n){cout << n;if (n % 2 == 0) {cout << " is even" << endl;evenCount++;}else {cout << " is odd" << endl;}});cout << "There are " << evenCount << " even numbers in the vector." << endl;getchar();return 0; }
参考资料
百度百科
《Visual C++2010权威开发指南》
转载于:https://www.cnblogs.com/wuyudong/p/c11-lambda.html
C++11中的Lambda表达式相关推荐
- 什么是C ++ 11中的lambda表达式?
本文翻译自:What is a lambda expression in C++11? What is a lambda expression in C++11? 什么是C ++ 11中的lambda ...
- C++ 11中的Lambda表达式
1. 概述 C++ 11 中的 Lambda 表达式用于定义匿名类(anonymous class).创建匿名类对象,以简化编程工作.编译器为该类添加操作符重载函数void operator()(ar ...
- 探索Java语言与JVM中的Lambda表达式
2019独角兽企业重金招聘Python工程师标准>>> 转载来源:http://www.admin10000.com/document/1291.html Lambda表达式是自Ja ...
- C++中的Lambda表达式详解
函数对象与Lambdas 你编写代码时,尤其是使用 STL 算法时,可能会使用函数指针和函数对象来解决问题和执行计算.函数指针和函数对象各有利弊.例如,函数指针具有最低的语法开销,但不保持范围内的状态 ...
- lambda qt 参数 槽函数_C++中的lambda表达式用法
#include <QCoreApplication> #include <QDebug> int main(int argc, char *argv[]) {QCoreApp ...
- Qt5中使用lambda表达式
c11新特性中加入了lambda表达式,所以Qt 也支持 需在.pro文件中加入 CONFIG += c++11例子: 1 QString program = "C:/Windows/Sys ...
- C++11新特性——λ(lambda)表达式详解
C++11新特性--λ(lambda)表达式 C++11中引入了λ表达式,它可以用来定义一个内联(inline)的函数,作为一个本地的对象或者一个参数.有了λ表达式,我们可以很方便的使用stl标准库. ...
- Python中的Lambda表达式
Lambda表达式 (Lambda Expressions) Lambda Expressions are ideally used when we need to do something simp ...
- android studio lambda插件,在Android Studio中使用Lambda表达式(retrolambda)
在Android Studio中使用Lambda表达式 要在Android Studio中使用Lambda表达式,需要借助一个gradle插件来完成. A gradle plugin for gett ...
最新文章
- import h5py ImportError: DLL load failed: the specified module could not be found
- python自学时间-Python 从入门到精通:一个月就够了!
- C编译器、链接器、加载器详解
- log--求自然对数
- java后台如何实现让用户可以在页面修改数据表_长见识了,Kotlin + SpringBoot + JPA 整合开发比Java更爽......
- 人工智能与大数据的完美结合 1
- mycat管理mysql_Mycat用户和权限控制管理
- 【面试】5道JAVA笔试算法题
- 解决 此 Flash Player 与您的地区不相容 问题
- vnc远程访问linux服务器,如何通过 VNC 远程访问 Linux 虚拟机
- 从小锁匠铺到工业造纸巨头,这家德国百年家族企业不断改写世界工程技术史 | 能动观察...
- Linux学习(完整)
- Obsidian好用的Markdown工具
- laravel-admin / Dcat admin 上传Excel并导入数据到数据库
- LDAP服务器不支持chap认证,终端使用EIA进行PEAP-GTC认证失败的原因分析
- 高中数学向量巨难题型四心问题解题技巧
- 2015年职称计算机考试宝典,2015年度职称计算机考试宝典.doc
- PowerBI网关on-premises data gateway无法登录账号的问题及解决方法
- iOS进阶 - pod install 与 pod update 读这一篇就够了
- Location iOS12.3驱动分享
热门文章
- 解决Office 2010出现the setup controller has encountered a problem...
- MinGW-w64安装教程——著名C/C++编译器GCC的Windows版本
- 超过resnet的图片分类网络
- 基于yolo4和yolo3(pytorch)的口罩识别的对比
- 卷积神经网络的实际意义
- 推荐一些网站给大家[转]
- 学习笔记:vsphere6 迁移物理机,指定被迁移的IP报错
- BZOJ-1257-[CQOI2007]余数之和sum
- BZOJ 4517: [Sdoi2016]排列计数 [容斥原理]
- Android开发之三种动画