• C++——Lambda表达式


    0.使用场景---只有一两个地方使用的简单操作

    独立出来一个函数,但这个函数实现相对简单并且可能在整个项目只使用了一次(即不存在复用的情况),那么这个时候我们就可以考虑使用下lambda表达式了。

    ?既然只使用一次,那直接写全代码不久醒了,为啥要函数呢?——因为lambda可以捕获局部变量

    bool check_size(const string &s, string::size_type sz)
    {
        return s.size() >= sz;
    }
    
    //wc:第一个满足size>sz的元素 auto wc
    = find_if (words.begin(),words.end(),[sz](const string &a) {return a.size()>=sz;});

    函数check_size()无法作为find_if的参数。而且需要考虑如何

    参考:https://blog.csdn.net/qq_34199383/article/details/80469780

    0.1 比较大小

    //1.传统方法
    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    bool compare(int& a, int& b)
    {
        return a > b;
    }
    
    int main(void)
    {
        int data[6] = { 3, 4, 12, 2, 1, 6 };
        vector<int> testdata;
        testdata.insert(testdata.begin(), data, data + 6);
        // 排序算法
        sort(testdata.begin(), testdata.end(), compare);    // 升序
    
        return 0;
    }
    /*******************************************/
    //2.lambda表达式
    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    int main(void)
    {
        int data[6] = { 3, 4, 12, 2, 1, 6 };
        vector<int> testdata;
        testdata.insert(testdata.begin(), data, data + 6);
    
        sort(testdata.begin(), testdata.end(), [](int a, int b){ return a > b; });
    
        return 0;
    }

    0.2 auto 和function 接受lambda表达式的返回

    #include <iostream>
    #include <functional>
    using namespace std;
    
    int main(void)
    {
        int x = 8, y = 9;
        auto add = [](int a, int b) { return a + b; };
        std::function<int(int, int)> Add = [=](int a, int b) { return a + b; };
    
        cout << "add: " << add(x, y) << endl;//17
        cout << "Add: " << Add(x, y) << endl;//17
    
        return 0;
    }

    0.3 使用lambda表达式来实现递归算法

    #include <iostream>
    #include <functional>
    using namespace std;
    
    int main(void)
    {
        std::function<int(int)> recursion = [&recursion](int n) { 
            return n < 2 ? 1 : recursion(n - 1) + recursion(n - 2); 
        };
    
        // 我们来检测下我们的结果
        cout << "recursion(2):" << recursion(2) << endl;//2
        cout << "recursion(3):" << recursion(3) << endl;//3
        cout << "recursion(4):" << recursion(4) << endl;//5
    
        return 0;
    }

    0.4  重用代码段,但是避免函数传很多参数

    void TestFun()
    {
        int a, b, c;
        .....    // 巴拉巴拉的一堆变量
    
        // 代码块改成如下 使用&还是=或者既有&又有=根据自己实际情况决定
        // param可以看做这个lambda中不同的变量
        auto lambdaFun = [&](int param) -> void {
            // 这里是可以直接调用到TestFun中的变量
            // 使用a、b、c....一堆变量
        }
    
        if (条件1)
        {
            lambdaFun(param1);
        }
        if (条件2)
        {
            lambdaFun(param2);
        }
        if (条件3)
        {
            lambdaFun(param3);
        }
    }

    1.本质:未命名的内联函数

    [capture list] (parameter list) ->return type 
    { 
        function body
    }
    //capture list 捕获列表,函数中定义的局部变量列表,通常为空
    //lambda表达式必须使用尾置返回——return **

    2.可以忽略返回类型,参数列表,但必须包含捕获列表和函数体

    auto f =[] {return 42;}

    3.捕获列表

    auto wc = find_if(words.begin(), words.end(),[sz](const string &a) { return a.size() >= sz;} );

     4.变量截取的方式

    • [] 不截取任何变量
    • [&] 截取外部作用域中所有变量,并作为引用在函数体中使用
    • [=] 截取外部作用域中所有变量,并拷贝一份在函数体中使用
    • [=, &foo] 截取外部作用域中所有变量,并拷贝一份在函数体中使用,但是对foo变量使用引用
    • [bar] 截取bar变量并且拷贝一份在函数体重使用,同时不截取其他变量
    • [this] 截取当前类中的this指针。如果已经使用了&或者=就默认添加此选项。

     5.lambda表达式产生的类不含有默认构造函数、赋值运算符、默认析构函数;

     6.lambda表达式是一种简易的定义函数对象类的方式。??如何定义?有何用处?

    l参考:

    https://www.cnblogs.com/smiler/p/4095723.html

    5.返回类型:单一的return语句;多语句则默认返回void;否则报错,应指定返回类型

    //正确,单一return语句
    transform(vi.begin(),vi.end(),vi.begin(), [] (int i) { 
        return i<0? -i; i;});
    
    //错误。不能推断返回类型
    transform(vi.begin(),vi.end(),vi.begin(), [] (int i) { 
        if (I<0) return -i;
        else return i;})
    
    //正确,尾置返回类型
    transform(vi.begin(),vi.end(),vi.begin(), [] (int i) ->int
    {     if (I<0) return -i;
        else return i;})

    6.bind()

    7.using std::placeholders::_1;

    8.示例

    stable_sort(words.begin(), words.end(), [](const string& a, const string& b)
        {    return a.size()<b.size();});
    class ShorterString{
    public:
        bool opereator()(const string &s1,const string &s2) const
            {return s1.size()<s2.size();} 
    };
    stable_sort(words.begin(), words.end(), ShorterString{));
    auto wc = find_if(words.begin(), words.end(), [sz] (const string& a)
        {  return a.size()>=sz;});//返回第一个指向满足条件元素的迭代器
    class SizeComp{
        SizeComp(size_t n):sz(n) { }
        bool operator()(const string &s) const
        { return s.size()>=sz;}
    private:
        size_t sz;
    };
    
    auto wc = find_if(words.begin(), words.end(),SizeComp(sz));
    
    
  • 相关阅读:
    一点点
    第四章:检查产品说明书
    这是一个动画效果,一个圆在桌面上动
    border-image的拉伸和平铺
    用js实现左右阴影的切换
    伪样式:hover ,:active,:focus
    画一个DIV并给它的四个角变成圆形,且加上阴影
    【转】asp.net 项目在 IE 11 下出现 “__doPostBack”未定义 的解决办法
    Full postback triggered by LinkButton inside GridView inside UpdatePanel
    苹果IOS开发者账号的区别,企业账号,个人账号,公司团队账号,教育账号
  • 原文地址:https://www.cnblogs.com/yrm1160029237/p/11494965.html
Copyright © 2020-2023  润新知