c++11 lambda

lambda 表达式的应用场景
1、延迟调用
2、链式调用
3、声明式编程,减少函数定义。

链式调用
1、递归,先执行最开始的代码。套娃,没添加一个then 就套一层。执行过程是,先执行m_fun, 然后在执行fun;
2、class Task<R(Args…)> ,类型推导,将类型拆分成2部分
3、R run(Args&&… args) ,加万能引用
4、m_fun(std::forward(args)…); 使用forward 进行完美转发

/**
 * lambda 的demo
 *
 * 田志泽 Tian zhize
 * tianzhize137@163.com
 *
 * 优点:
 * 1、声明式编程,更加简洁
 * 2、减少了函数的定义,免除了大量函数的维护,提高了可读性
 *
 */
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>

/**
 * 推导返回值类型
 * 1、lambda 表达式的默认是const
 * 2、没有捕获变量的可以赋值函数指针,捕获的不可以
 */

void typeDeduction() {
    auto f = [](int a) { return a + 1; };  //可以推导返回值类型
    // auto f1 = [](int a) { return {1,1};}//无法推导

    // 1、lambda 表达式的默认是const
    int a = 0;
    auto f1 = [=]() mutable { return a++; };

    // mutable 可以修改外部捕获变量
    // auto f2 = [=]() {
    //     return a++;
    // };

    //结合std::funtion 和 bind
    std::function<int(int)> func1 = [=](int c) { return a + c; };
    std::function<int()> func2 = std::bind([](int a) { return a; }, 10);
    std::function<int()> func3 = std::bind(func1, 10);

    // 2、没有捕获变量的可以赋值函数指针,捕获的不可以
    typedef void (*Ptr)();
    Ptr p = []() {};
    // Ptr p1 = [=](){};
}

/**
 * 声明式编程,更加简洁,改动量很小
 */
void decl() {
    std::vector<int> vec;
    for_each(vec.begin(), vec.end(), [](int a) {
        //处理
    });

    // 查找大于5 小于 10
    // 如果没有返回值接收,会报错ignoring return value of function declared with warn_unused_result attribute
    int count = std::count_if(vec.begin(), vec.end(), [](int a) -> bool {
        bool b = a > 5 && a <= 10;
        return b;
    });
}

/**
 * 链式调用
 * 1、采用递归的方式,压栈
 * 2、
 */
#include <functional>

template <class T>
class Task;

template <class R, class... Args>
class Task<R(Args...)> {
public:
    Task(std::function<R(Args...)>&& f) : m_fun(f) {
    }
    Task(std::function<R(Args...)>& f) : m_fun(f) {
    }

    R run(Args&&... args) {
        return m_fun(std::forward<Args>(args)...);
    }

    template <class F>
    Task<typename std::result_of<F(R)>::type(Args...)> then(F&& f) {
        //获取返回值
        using return_type = typename std::result_of<F(R)>::type;
        //
        auto fun = std::move(m_fun);
        return Task<return_type(Args...)>([fun, &f](Args&&... args) {
            //前一个的输出作为下一个输入
            auto ret = fun(std::forward<Args>(args)...);
            return f(ret);
        });

        //重新构建一个临时对象,task, 新task 中,新的lambda 表达式是,先执行m_fun. 在执行传入的。
        //所以调用的顺序 调用1 - 调用2 ,调用1的返回值作为 调用2的参数。
    }

    std::function<R(Args...)> m_fun;
};

/**
 * 再次编写一次加强记忆
 */
template <class T>
class TaskA;
template <class R, class ...Args> 
class TaskA<R(Args...)> {
public:
    TaskA(std::function<R(Args...)> &&f) : m_fun(f){}
    TaskA(std::function<R(Args...)> &f) : m_fun(f){}

    R run(Args...args) {
        return m_fun(std::forward<Args>(args)...);
    }

    template<class F>
    auto then(F && f) -> TaskA<typename std::result_of<F(R)>::type(Args...)>{
        // 获取F的返回值
        using NewType = typename std::result_of<F(R)>::type(Args...);

        // 新创建一个task 对象
        auto newFun = [&f,this](Args&&...args){
            auto ret = m_fun(std::forward<Args>(args)...);
            return f(ret);
        };

        return TaskA<NewType>(newFun);
    }

    std::function<R(Args...)> m_fun;
};

void test_lambda_task() {
    //调用过程 task.then({调用1}).then({调用2}).run(1);
    // 套娃,没添加一个then 就套一层。执行过程是,先执行m_fun, 然后在执行fun;
    Task<int(int,int)> task{[](int a,int b) {
        std::cout << 1 << std::endl;
        return a + 1;
    }};

    auto task1  = task.then([](int a)->double {
            std::cout << 2 << std::endl;
            return a + 2;
        });
    auto task2 = task1.then([](double a) {
        std::cout << 3 << std::endl;
            return a + 2;
    });

    task2.run(1,2);
}

void test_lambda_taskA() {
    //调用过程 task.then({调用1}).then({调用2}).run(1);
    // 套娃,没添加一个then 就套一层。执行过程是,先执行m_fun, 然后在执行fun;
    TaskA<int(int,int)> task{[](int a,int b) {
        std::cout << 1 << std::endl;
        return a + 1;
    }};

    auto task1  = task.then([](int a)->double {
            std::cout << 2 << std::endl;
            return a + 2;
        });
    auto task2 = task1.then([](double a) {
        std::cout << 3 << std::endl;
            return a + 2;
    });

    task2.run(1,2);
}

int main() {
    test_lambda_task();
    test_lambda_taskA();
    system("pause");
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值