最新公告
  • 欢迎您光临波比源码,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入我们
  • C++拾遗–lambda表达式原理

                          C++拾遗–lambda表达式原理

    前言

        lambda表达式是在C++11新标准中提出的。在lambda表达式中,我们集中梳理了1下它的使用。现在来讨论下它的实现原理。

    正文

    1.函数对象

    类的对象跟括号结合,表现出函数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;
    }

    运行


    这个示例说明函数对象的本质是重载了函数调用运算符。当1个类重载了函数调用运算符()后,它的对象就成了函数对象。这是理解lambda表达式内部实现的基础。


    2.lambda表达式原理

    原理:编译器会把1个lambda表达式生成1个匿名类的匿名对象,并在类中重载函数调用运算符。

    我们从最简单的lambda表达式入手,从易到难

    2.1 无捕获列表和参数列表

    auto print = []{cout << "zhangxiang" << endl; };

    编译器会把这1句翻译成以下情形:

    //用给定的lambda表达式生成相应的类
    class print_class
    {
    public:
    void operator()(void) const
    {
    cout << "zhangxiang" << endl;
    }
    };
    //用构造的类创建对象,print此时就是1个函数对象
    auto print = print_class();

    生成类的类名命名规则可以多变,不1定非得这样。


    2.2 无捕获列表但有参数列表

    auto add = [](int a, int b){return a + b; };

    编译器会把这1句翻译成以下情形:

    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,name
    auto 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);

    运行效果是1样的,就不演示了。


    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;
    };

    经过测试,效果也是1样的。

    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();


    默许情况下,经过值捕获的变量是不可以被修改的,除非在参数列表后加关键字mutable。以上代码展现了,对应类中mutable是如何加的。固然还有另外一种实现方法,只要lambda表达式加了mutable,重载函数调用运算符时就不加const修饰。


    总结

    以上这些示例代码基本上把各种情形的lambda表达式的实现原理都展现出来了,仔细想一想还是挺容易的。



    本专栏目录

    • C++拾遗 目录
    所有内容的目录
    • CCPP Blog 目录
    波比源码 – 精品源码模版分享 | www.bobi11.com
    1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
    2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
    3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
    4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
    5. 如有链接无法下载、失效或广告,请联系管理员处理!
    6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
    7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!

    波比源码 » C++拾遗–lambda表达式原理

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    波比源码
    一个高级程序员模板开发平台
    升级波友尊享更多特权立即升级