C++ 实现then,lambda链式调用

19 篇文章 0 订阅
6 篇文章 0 订阅

lambda 链式调用

C++11支持lambda和function,在一些延迟计算的场景下,这个链式调用的需求更加强烈。链式调用的目的是,将多个函数按照前一个的输出作为下一个的输入串起来,然后推迟到某个时刻再计算。C++中链式调用比较少见,因为实现比较复杂。

template<typename T>
class Task;
template<typename R,typename...Args>
class Task<R(Args...)>{
    public:
    Task(std::function<R(Args...)> && f) : m_fn(std::move(f)){std::cout <<
    	"move construct func name : "<<__func__<< std::endl;}
    Task(std::function<R(Args...)> & f) : m_fn(f){std::cout <<"construct func name : "<<
    	__func__<< std::endl;}
    R run(Args&& ... args){
        std::cout <<"exec function,func name : "<<__func__<< std::endl;
        return m_fn(std::forward<Args>(args)...); //perfect
    }
    // continue exec
    template<typename F>
    auto then(F && f)->Task<typename std::result_of<F(R)>::type(Args...)>{
        std::cout <<"then -> "<<i<< std::endl;i++;
        using return_type = typename std::result_of<F(R)>::type; //get F return type
        auto func = std::move(m_fn);
        return Task<return_type(Args...)>([func,f](Args&& ...args){
            return f(func(std::forward<Args>(args)...));
        });
    }
    private:
    std::function<R(Args...)> m_fn;
};

void TestTask(){
    Task<int(int)> task([](int i){std::cout <<"init :"<<i<< std::endl;return i;});
    std::string str = "join in lambda then : ";
    auto res = task.then([&str](int i){str += "then 1\t";std::cout <<"first:"<<i<< 
    	std::endl;return i + 1;})
    .then([&str](int i){str += "then 2\t";std::cout <<"second:"<<i<<std::endl;return i + 2;})
    .then([&str](int n){str += "then 3\t";std::cout <<"third:"<<n<< 
    	std::endl;return std::make_tuple(n + 3,"n + 3");})
    .then([&str](auto n){str += "then 4\t";std::cout <<"fouth:"<< 
    	std::get<0>(n)<<"tuple string : "<<std::get<1>(n)<< std::endl;
    	return std::make_tuple(std::get<0>(n) + 4,"then exec ecnd");
    	}).run(1);
    std::cout <<"result tuple value : "<<std::get<0>(res)<<"   result tuple string : "<<
    	std::get<1>(res)<< "   result string : "<<str<<std::endl;
}

auto fu(int i){
    auto f = std::async([](int i){
        std::cout <<"sleep two "<<i<<" seconds..."<< std::endl;
       // std::chrono::milliseconds dre(i * 1000);
       // std::this_thread::sleep_for(dre);
        return i * i;
    },i);
    return std::forward<decltype(f)>(f);
}

void testFuture(){
    std::cout <<"at testFuture func thread : "<<std::this_thread::get_id()<< std::endl;
    typedef std::future<int> A;
    typedef std::result_of<decltype(fu)*(int)>::type B;
    static_assert(std::is_same<A,B>::value,"not equal");
    Task<std::result_of<decltype(fu)&(int)>::type(int)> task(fu);
    auto t = task.then([](auto o){
        std::cout <<"wait value ..."<< std::endl;
        std::cout <<"at first then func thread : "<<std::this_thread::get_id()<< std::endl;
        auto ii = o.get() + 100;
        auto f = std::async([](int i){
            std::cout <<"new value :"<<i<<" .."<< std::endl;
            std::cout <<"]async in thread : "<<std::this_thread::get_id()<< std::endl;
            //std::chrono::milliseconds dre(i * 1000);
            //std::this_thread::sleep_for(dre);
            return i * i;
        },ii);
        return std::forward<decltype(f)>(f);}) 
    .then([](auto o){
        std::cout <<wait value ...\n";
        std::cout <<"]at second then func thread : "<<std::this_thread::get_id<< std::endl; 
        //std::chrono::milliseconds dre(2000); //sleep 2 seconds
        //std::this_thread::sleep_for(dre);
        std::cout <<"wait last value...,,,,,,,,,,,,,,,,,,,,,,,,,,"<< std::endl;
        return o.get() + 10000;})
    .then([](auto o){
        std::cout <<"fouth then"<< std::endl;
        auto ff = std::async([](auto i){
            std::cout <<"wait value ...\n";
            std::cout <<"at third then func thread : "<<std::this_thread::get_id<< std::endl; 
            int all = 2134;
            for(auto ii = 0; ii < i; ++ii){
                //std::cout<<ii;
                all += (ii % 3 == 0 && ii > all * 1.5) ? 1 : 2;
            }
            std::cout<<""<<all<<"\n";
            return all;
        },o);
        return std::forward<decltype(ff)>(ff);})
    .run(2); // 2 seconds
    std::cout<<"future get : "<<t.get()<<"\n";
}

int main(){
    TestTask();  // lambda exec func
    testFuture(); //lambda exec thread
}
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C语言中,没有lambda表达式的概念。但是,你可以使用函数指针来实现类似于lambda表达式的功能。下面是一个示例代码,演示如何使用函数指针调用类中的函数: ```c #include <stdio.h> // 定义一个类 typedef struct { int x; int y; void (*print)(int, int); } Point; // 类中的函数 void printPoint(int x, int y) { printf("(%d, %d)\n", x, y); } // 定义一个函数,接收一个函数指针作为参数 void callFunction(void (*func)(int, int), int x, int y) { func(x, y); } int main() { // 创建一个对象 Point p = {10, 20, printPoint}; // 调用类中的函数 p.print(p.x, p.y); // 使用函数指针调用类中的函数 callFunction(p.print, p.x, p.y); return 0; } ``` 代码中,我们首先定义了一个Point类,包含两个成员变量x和y,以及一个print函数指针。print函数指针指向一个函数,用于打印Point对象的坐标。 接着,我们定义了一个函数callFunction,接收一个函数指针和两个参数。该函数用于调用传入的函数指针,并将两个参数传递给该函数。 在main函数中,我们创建了一个Point对象p,并调用了其print函数指针,输出对象的坐标。接着,我们使用函数指针调用了p的print函数,输出了同样的结果。 需要注意的是,函数指针的类型必须与类中的函数指针类型相同。在本例中,print函数指针的类型为void (*)(int, int),即接收两个int参数并返回void。因此,在调用callFunction函数时,传入的函数指针参数的类型也必须为void (*)(int, int)。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值