Loki之Funtion
阅读Loki中Funtion源码之后的个人理解,该库归纳起来可以说有三层(C++设计新思维列举到2个参数,此处列举到3个参数),要记住C++的模板其实就是C语言高级的宏定义,如果用户没有用到对应的模板编译器是不会生成对应代码的。
第一层:
template <typename R, template <class, class> class ThreadingModel>
class FunctorImpl<R, NullType, ThreadingModel>
: public Private::FunctorImplBase<R, ThreadingModel>
{
public:
typedef R ResultType;
virtual R operator()() = 0;
}; ////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 1 parameter
//////////////////////////////////////////////////////////////////////////////// template <typename R, typename P1, template <class, class> class ThreadingModel>
class FunctorImpl<R, Seq<P1>, ThreadingModel>
: public Private::FunctorImplBase<R, ThreadingModel>
{
public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
virtual R operator()(Parm1) = 0;
}; ////////////////////////////////////////////////////////////////////////////////
// class template FunctorImpl
// Specialization for 2 parameters
//////////////////////////////////////////////////////////////////////////////// template <typename R, typename P1, typename P2,
template <class, class> class ThreadingModel>
class FunctorImpl<R, Seq<P1, P2>, ThreadingModel>
: public Private::FunctorImplBase<R, ThreadingModel>
{
public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
virtual R operator()(Parm1, Parm2) = 0;
};
对应的还有virtual R operator()(Parm1, Parm2, Pram3) = 0; virtual R operator()(Parm1, Parm2, Pram3,Pram4...) = 0总共有15个参数为止;每个operator()操作符都是纯虚函数,这样上层类继承之实现多态。
需要注意的是每个模板特化的FunctorImpl只有一个R operator(),父类FunctorImplBase暂时不用关注
第二层:
template <class ParentFunctor, typename Fun>
class FunctorHandler
: public ParentFunctor::Impl
{
typedef typename ParentFunctor::Impl Base;
private:
Fun f_;
public:
typedef typename Base::ResultType ResultType;
typedef typename Base::Parm1 Parm1;
typedef typename Base::Parm2 Parm2;
typedef typename Base::Parm3 Parm3;
typedef typename Base::Parm4 Parm4;
typedef typename Base::Parm5 Parm5;
typedef typename Base::Parm6 Parm6;
typedef typename Base::Parm7 Parm7;
typedef typename Base::Parm8 Parm8;
typedef typename Base::Parm9 Parm9;
typedef typename Base::Parm10 Parm10;
typedef typename Base::Parm11 Parm11;
typedef typename Base::Parm12 Parm12;
typedef typename Base::Parm13 Parm13;
typedef typename Base::Parm14 Parm14;
typedef typename Base::Parm15 Parm15; FunctorHandler(const Fun& fun) : f_(fun) {} LOKI_DEFINE_CLONE_FUNCTORIMPL(FunctorHandler) #ifdef LOKI_FUNCTORS_ARE_COMPARABLE bool operator==(const typename Base::FunctorImplBaseType& rhs) const
{
// there is no static information if Functor holds a member function
// or a free function; this is the main difference to tr1::function
if(typeid(*this) != typeid(rhs))
return false; // cannot be equal const FunctorHandler& fh = static_cast<const FunctorHandler&>(rhs);
// if this line gives a compiler error, you are using a function object.
// you need to implement bool MyFnObj::operator == (const MyFnObj&) const;
return f_==fh.f_;
}
#endif
// operator() implementations for up to 15 arguments ResultType operator()()
{ return f_(); } ResultType operator()(Parm1 p1)
{ return f_(p1); } ResultType operator()(Parm1 p1, Parm2 p2)
{ return f_(p1, p2); } ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
{ return f_(p1, p2, p3); }
//后面还有operator()(Parm1 p1, Parm2 p2, Parm3 p3, Pram4 p4....)
FunctorHandler继承自模板参数ParentFunctor内部定义的类型Impl,待会看到第三层的时候就会发现其实是对应参数类型的FunctorImpl的某个特化版本,这样FunctorHandler实现了FunctorImpl中的重载operator()的虚函数,
而其中的成员Fun f_可能为函数指针或者函数对象,即用户传递进来的参数
第三层:
template <typename R = void, class TList = NullType,
template<class, class> class ThreadingModel = LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL>
class Functor
{ private:
std::auto_ptr<Impl> spImpl_;
public:
// Handy type definitions for the body type
typedef FunctorImpl<R, TList, ThreadingModel> Impl;
typedef R ResultType;
typedef TList ParmList;
typedef typename Impl::Parm1 Parm1;
typedef typename Impl::Parm2 Parm2;
typedef typename Impl::Parm3 Parm3;
//...... // Member functions Functor() : spImpl_(0)
{} Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get()))
{} Functor(std::auto_ptr<Impl> spImpl) : spImpl_(spImpl)
{} template <typename Fun>
Functor(Fun fun)
: spImpl_(new FunctorHandler<Functor, Fun>(fun))
{} template <class PtrObj, typename MemFn>
Functor(const PtrObj& p, MemFn memFn)
: spImpl_(new MemFunHandler<Functor, PtrObj, MemFn>(p, memFn))
{} ResultType operator()() const
{
LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
return (*spImpl_)();
} ResultType operator()(Parm1 p1) const
{
LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
return (*spImpl_)(p1);
}
ResultType operator()(Parm1 p1, Parm2 p2) const
{
LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
return (*spImpl_)(p1, p2);
}
ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3) const
{
LOKI_FUNCTION_THROW_BAD_FUNCTION_CALL
return (*spImpl_)(p1, p2, p3);
}
//......
注意成员std::auto_ptr<Impl> spImpl_;其类型是FunctorImpl根据模板参数TList会选择对应的特化版本,它是FunctorHandler的基类,为什么这么说请看对应的构造函数就明白
template <typename Fun>
Functor(Fun fun)
: spImpl_(new FunctorHandler<Functor, Fun>(fun))
{}
该构造函数也是模板函数,模板参数fun是用户传递进来对应的函数指针或者仿函数,还记得FunctorHandler继承自Functor::Impl吗?这时候就是子类FunctorHandler赋值给基类指针spImpl实现了多态,当调用operator()时候转发的过程是
(*spImpl_)(...)
spImpl的operator()为虚函数转发给子类FunctorHandler的operator();FunctorHandler调用用户传递进来的函数指针或者仿函数
暂时写到这,后期完善
Loki之Funtion的更多相关文章
- C++三大库boost、loki、stlport
转: STL是一个标准,各商家根据这个标准开发了各自的STL版本.而在这形形色色的STL版本中,SGI STL无疑是最引人瞩目的一个.这当然是因为这个STL产品系出名门,其设计和编写者名单中,Alex ...
- 使用c++11改写loki的TypeList
最近看了C++11的一些特性,最感兴趣的是可变模板参数,自动类型推断和匿名函数. Loki中的TypeList,是需要递归定义的,并且需要一个NullType作为尾节点. 可变模板参数使得实现Type ...
- c++异常处理第四篇---不使用try catch语句,使用Loki::ScopeGuard
转载:神奇的Loki::ScopeGuard 2011-07-05 12:52:05 分类: C/C++ 转载:http://blog.csdn.net/fangqu/article/details/ ...
- 【转】tars源码漫谈第1篇------tc_loki.h (牛逼哄哄的loki库)
loki库是C++模板大牛Andrei写的, 里面大量运用模板的特性, 而tc_loki.h借用了loki库的部分代码, 形成了一个基本的文件tc_loki.h, 来看看: #ifndef __TC_ ...
- Oracle ERP Audit Funtion in R12.2.4
M1 JOB NAME: 164839 TABLE NAME: WIP_REQUIREMENT_OPERATIONS Request name: AuditTrail Update Tables O ...
- 使用loki+ mtail + grafana + prometheus server分析应用问题
loki 是一个方便的类似prometheus 的log 系统,mtail 是一个方便的日志提取工具, 可以暴露为http 服务——支持导出prometheus metrics 环境准备 docker ...
- 使用 loki grafana 分析nginx 请求日志
loki 是类似prometheus 的log 可视化展示.收集系统,已经集成在grafana 6.0 版本中了 说明: 测试环境使用了docker-compose 运行 环境准备 docker-co ...
- loki grafana 团队开源的,类似Prometheus 的log 系统
Prometheus 主要面向的是metrics,但是loki 是log,这样加上grafana 强大的可视化以及alert能力, 我们可以做好多事情,loki 的设计来源于Prometheus. 组 ...
- JS funtion()中URL不跳转后台action问题
JS funtion()中URL不跳转后台action问题 今天遇到一个百思不得其解的问题,到现在解决了,但是仍然不知道所以然(估计是因为域名不一致导致的),记录一下 $.get(actionUrl, ...
随机推荐
- lockf函数的使用
#include<stdio.h> #include<unistd.h> void main() {int p1,p2,i; while((p1=fork())==-1);// ...
- 2018-11-21 ko.pureComputed的使用
以前一直在想,ko.pureComputed 好像用不上.看起来高大上. 今天在修复一个bug时,发现了它的妙处. 在修改商品列表的页面,弹出一个新增商品的页面.关闭之后,怎么通知修改商品列表的页面发 ...
- setTranslatesAutoresizingMaskIntoConstraints和setFrame组合使用导致的异常
在用Ojbect-c开发OSX应用的时候需要用到自定义控件并用代码进行布局,很自然地就使用了setTranslatesAutoresizingMaskIntoConstraints和setFrame组 ...
- JAVASCRIPT+DHTML实现表格拖动
自已做的,本来想在网上找前辈们做的,可是总找不到这种例子,要么找出来的太复杂, 要么就没法用,索性自己写了一个.看看还可以用!贡献出来,估计和我一样的菜鸟用的着! <html> <s ...
- linux 下简单的ftp客户端程序
该ftp的客服端是在linux下面写,涉及的东西也比较简单,如前ftp的简单介绍,知道ftp主要的工作流程架构,套接字的创建,还有就是字符串和字符的处理.使用的函数都是比较简单平常易见的,写的时候感觉 ...
- Codeforces Round #266 (Div. 2)
http://codeforces.com/contest/466 噗,b没写出来啊.a写完后过了40分钟了啊,罚时4次啊!果然太弱 总结: a题看错题,没有考虑m>=n其实也是可行的,导致调了 ...
- CSS伪类选择器 - nth-child(an+b):
CSS伪类选择器 - nth-child(an+b): 第一种:简单数字序号写法:nth-child(number)直接匹配第number个元素.参数number必须为大于0的整数.li:nth-ch ...
- 常用的jQuery前端技巧收集
调试时巧用console.log(),这比用alert()方便多了. jquery易错点:元素拼接的时候,元素还未添加到DOM,就用该预添加元素操作. ajax动态获取的数据,还没有装载html元素, ...
- ASP.NET MVC 随想录
http://www.cnblogs.com/OceanEyes/category/696137.html
- AWS CLI 【S3】
1.创建一个桶&删除一个桶 root@syavingc:~# aws s3 mb s3://syavingc #创建一个桶 make_bucket: syavingc root@syaving ...