C++拾遗--lambda表达式原理
来源:互联网 发布:淘宝培训学校靠谱吗 编辑:程序博客网 时间:2024/06/01 10:19
C++拾遗--lambda表达式原理
前言
lambda表达式是在C++11新标准中提出的。在lambda表达式中,我们集中梳理了一下它的使用。现在来讨论下它的实现原理。
正文
1.函数对象
类的对象跟括号结合,表现出函数一般的行为,这个对象可以称作是函数对象。
#include <iostream>using namespace std;class MyClass{public://重载函数调用运算符()int operator()(int i){return i;}};int main(){MyClass my;//my()的调用行为似同函数int i = my(1); //本质是调用 my.operator()(1)cout << "i = " << i << endl;cin.get();return 0;}运行
这个示例说明函数对象的本质是重载了函数调用运算符。当一个类重载了函数调用运算符()后,它的对象就成了函数对象。这是理解lambda表达式内部实现的基础。
2.lambda表达式原理
原理:编译器会把一个lambda表达式生成一个匿名类的匿名对象,并在类中重载函数调用运算符。
我们从最简单的lambda表达式入手,从易到难
2.1 无捕获列表和参数列表
auto print = []{cout << "zhangxiang" << endl; };编译器会把这一句翻译成如下情形:
//用给定的lambda表达式生成相应的类class print_class{public:void operator()(void) const{cout << "zhangxiang" << endl;}};//用构造的类创建对象,print此时就是一个函数对象auto print = print_class();生成类的类名命名规则可以多变,不一定非得这样。
2.2 无捕获列表但有参数列表
auto add = [](int a, int b){return a + b; };编译器会把这一句翻译成如下情形:
class add_class{public:auto operator()(int a, int b) const{return a + b;}};auto add = add_class();
2.3 有捕获列表,参数列表可选
由于捕获方式分为两种:引用捕获、值捕获,故此种情况下,又可细分。
2.3.1 值捕获
int year = 19900212;char *name = "zhangxiang";//采用值捕获,捕获所有的已定义的局部变量,如year,nameauto print = [=](){cout << year << ends << name << endl;};翻译
int year = 19900212;char *name = "zhangxiang";class print_class{public://根据捕获列表来决定构造函数的参数列表形式print_class(int year, char *name) :year(year), name(name){}void operator()(void) const{cout << year << ends << name << endl;}private:int year;char *name;};auto print = print_class(a, str);运行效果是一样的,就不演示了。
2.3.2 引用捕获
int year = 19900212;char *name = "zhangxiang";auto print = [&](){year++;cout << year << ends << name << endl;};翻译
int year = 19900212;char *name = "zhangxiang";class print_class{public://由于是引用捕获,参数列表采用引用的方式print_class(int &year, char *&name) :year(year), name(name){}void operator()(void) const{year++; //编译通过,const对引用类型无效cout << year << ends << name << endl;}private:int &year;char *&name;};经过测试,效果也是一样的。
2.3.3 混合捕获
int year = 19900212;int shoes = 42;char *name = "zhangxiang";auto show = [&, shoes]()mutable{shoes++;year++;cout << year << ends << shoes << ends << name << endl;};翻译
int year = 19900212;int shoes = 42;char *name = "zhangxiang";class show_class{private:int &year;mutable int shoes;char *&name;public:show_class(int &year, int shoes, char *&name) :year(year), shoes(shoes), name(name){}void operator()(void)const{shoes++;year++;cout << year << ends << shoes << ends << name << endl;}};auto show = show_class(year, shoes, name);show();
总结
以上这些示例代码基本上把各种情形的lambda表达式的实现原理都展现出来了,仔细想想还是挺容易的。
本专栏目录
- C++拾遗 目录
所有内容的目录
- CCPP Blog 目录
2 0
- C++拾遗--lambda表达式原理
- C++拾遗--lambda表达式
- Lambda表达式 推算原理
- java8 lambda表达式原理
- java8 lambda表达式原理
- 【c/c++】Lambda表达式
- C#--Lambda表达式
- C#:Lambda 表达式
- C++lambda表达式
- C++lambda表达式
- C# Lambda表达式
- C++:lambda表达式
- C#Lambda表达式
- 【c++】lambda表达式
- C++lambda表达式简记
- c#lambda表达式复习
- [C++]Lambda表达式简介
- 【C#】理解Lambda表达式
- Matlab图像处理工具箱
- HDU1575 Tr A(矩阵快速幂)
- 循环-15. 统计素数并求和(20)
- cocos2d-x 2.2.3 创建项目的方法
- 百度地图开发之实现运动轨迹 <一>
- C++拾遗--lambda表达式原理
- Swift之网络请求框架封装
- 费马小定理
- linux网络代理设置(终端命令行的网络代理设置)
- MFC修改button的颜色、背景、边框、对话框标题
- 黑马程序员——iOS基础第一篇
- delphi xe7 fmx 复制到剪切板
- 使用JAVA调用中科院ICTCLAS2015分词系统
- Android 应用程序管理机制