(原创)c++11中 function/lamda的链式调用
关于链式调用,比较典型的例子是c#中的linq,不过c#中的linq还只是一些特定函数的链式调用。c++中的链式调用更少见因为实现起来比较复杂。c++11支持了lamda和function,在一些延迟计算的场景下,这个链式调用的需求更强烈了。链式调用要实现的目是,将多个函数按照前一个的输出作为下一个输入串起来,然后再推迟到某个时刻计算。c++中,目前看到PPL中有这样的用法。PPL中链式调用的例子:
int wmain()
{
auto t = create_task([]() -> int
{
return ;
}); // Create a lambda that increments its input value.
auto increment = [](int n) { return n + ; }; // Run a chain of continuations and print the result.
int result = t.then(increment).then(increment).then(increment).get();
wcout << result << endl;
} /* Output:
3
*/
例子中先创建一个task对象,然后连续的调用then函数,其实这个then中的lamda的形参可以是任意类型的,只要保证前一个函数的输出为后一个的输入就行。将这些task串起来之后,最后在需要的时候去计算结果,计算的过程是链式的,从最开始的函数开始计算一直到最后一个得到最终结果。这个task和他的链式调用
过程是很有意思的。不过PPL中的链式调用有一点不太好,就是初始化的task不能有参数,因为wait函数是不能接收参数的。经过一番探索,我觉得用c++11我可以做一个差不多链式调用的task,还可以弥补前面所说PPL task不太好的地方,即可以接收参数。其实关于链式调用的实现我之前有博文做了介绍,有兴趣的童孩点这里。不过我对之前的实现方式不太满意,觉得还是PPL这种链式调用方式更好。好了,下面看看我是如何实现和ppl类似的,可以实现链式调用的task。
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)){} Task(std::function<R(Args...)>& f) : m_fn(f){}
template<typename... Args> R Run(Args&&... args) { return m_fn(std::forward<Args>(args)...); } template<typename F> auto Then(F& f)->Task<typename std::result_of<F(R)>::type(Args...)> { return Task<typename std::result_of<F(R)>::type(Args...)>([this, &f](Args&&... args){
return f(m_fn(std::forward<Args>(args)...)); });
}
private:
std::function<R(Args...)> m_fn;
};
测试代码:
void TestTask()
{
Task<int(int)> task = [](int i){return i;};
auto result = task.then([](int a){return i+;}).then([](int a){return i+;}).then([](int a){return i+;}).run();
//result 7
}
可以看到,我的Task调用方式和PPL一致,更棒的是还可以接收参数了。也许有人有点疑惑,链式调用这个东西真的有用吗?至少目前看到PPL和TBB是这样用的,而且他对我的开发来说非常有用,至于我对他的具体应用暂且按下不表,后面就会知道我是如何用它了。
如果你觉得这篇文章对你有用,可以点一下推荐,谢谢。
c++11 boost技术交流群:296561497,欢迎大家来交流技术。
(原创)c++11中 function/lamda的链式调用的更多相关文章
- JavaScript设计模式-8.链式调用
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 关于JavaScript中的setTimeout()链式调用和setInterval()探索
http://www.cnblogs.com/Wenwang/archive/2012/01/06/2314283.html http://www.cnblogs.com/yangjunhua/arc ...
- JavaScript中的链式调用
链模式 链模式是一种链式调用的方式,准确来说不属于通常定义的设计模式范畴,但链式调用是一种非常有用的代码构建技巧. 描述 链式调用在JavaScript语言中很常见,如jQuery.Promise等, ...
- 编程中的链式调用:Scala示例
编程中的链式调用与Linux Shell 中的管道类似.Linux Shell 中的管道 ,会将管道连接的上一个程序的结果, 传递给管道连接的下一个程序作为参数进行处理,依次串联起N个实用程序形成流水 ...
- 疯狂的类构造器Builder模式,链式调用
疯狂的类构造器 最近栈长在做 Code Review 时,发现一段创建对象的方法: Task task = new Task(112, "紧急任务", "处理一下这个任务 ...
- 如何写 JS 的链式调用 ---》JS 设计模式《----方法的链式调用
1.以$ 函数为例.通常返回一个HTML元素或一个元素集合. 代码如下: function $(){ var elements = []; ;i<arguments.length;i++){ v ...
- Swift2.1 语法指南——可空链式调用
原档:https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programmi ...
- jQuery的XX如何实现?——2.show与链式调用
往期回顾: jQuery的XX如何实现?——1.框架 -------------------------- 源码链接:内附实例代码 jQuery使用许久了,但是有一些API的实现实在想不通.于是抽空看 ...
- js实现方法的链式调用
假如这里有三个方法:person.unmerried();person.process();person.married();在jQuery中通常的写法是:person.unmerried().pro ...
随机推荐
- github不能访问、加载css、js解决办法
很奇怪,白天在公司还能正常访问github,晚上回来访问却有问题,表现症状是页面加载慢,并且页面样式明显错乱. 在chrome下用F12开发者工具一看,有2条css和2条js 404 了,猜想应该是g ...
- android中巧妙更改spinner、AutoCompleteTextView分割线的颜色值(spinner AutoCompleteTextView divider color)
这个问题本来是个不大的问题,但是遇到了就会很郁闷,Android控件的api本身就不太够强大,这个小属性找了好久没找到,今天终于解决,分享给所有遇到这个问题的朋友. spinner下拉列表中间有一条黑 ...
- Dubbo OPS工具——dubbo-admin & dubbo-monitor
1. 前言 今年八月份的时候,查看github仓库,Dubbo OPS还提供了三种工具用于Dubbo的监控运维: 九月份,伴随着Dubbo的全面快速的升级,现在仓库里Dubbo OPS下这三个工具已经 ...
- JDBC连接方式有哪几种
2011-05-10 目前比较常见的JDBC驱动程序可分为以下四个种类: (1)JDBC-ODBC桥加ODBC驱动程序 JavaSoft桥产品利用ODBC驱动程序提供JDBC访问.注意,必须将OD ...
- python web中的并发请求
python web可以选择django,也可以选择flask,它们的原理差不多.flask比较轻量,下面写一段flask程序来说明python web对并发请求的处理. app.py import ...
- java struts2入门学习--OGNL语言常用符号和常用标签学习
一.OGNL常用符号(接上一篇文章): 1.#号 1)<s:property value="#request.username"/> 作用于struts2的域对象,而不 ...
- 给定数组a[1,2,3],用a里面的元素来生成一个长度为5的数组,打印出其排列组合
给定数组a[1,2,3],用a里面的元素来生成一个长度为5的数组,打印出其排列组合 ruby代码: def all_possible_arr arr, length = 5 ret = [] leng ...
- Redis学习之路(001)- Redis介绍以及安装(Linux)
redis是当前比较热门的NOSQL系统之一,它是一个key-value存储系统.和Memcached类似,但很大程度补偿了memcached的不足,它支持存储的value类型相对更多,包括strin ...
- c语言之函数参数传递之数组篇(转)
在VC中写程序都习惯了,一般数组作为函数实参时,最常用的方法就是引用和指针的方法,但是到C语言中就没有引用了,还有一种比较常用的方法: #include <stdio.h>void sor ...
- 树莓派进阶之路 (009) - 树莓派ftp脚本(原创)
FTP.sh #!/bin/sh cd echo "彻底卸载原有的ftp" sudo apt-get remove --purge vsftpd #(--purge 选项表示彻底删 ...