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

本文介绍了一种在C++中实现lambda链式调用的方法,通过自定义Task类和模板函数,使得多个函数可以按照前一个的输出作为下一个的输入进行串接,实现了延迟计算的功能。通过具体示例展示了如何使用链式调用处理数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值