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, ...
随机推荐
- js 開始时间,当前时间,结束时间的比較
//開始时间不能小于当前时间 function startTimeIsBigThanTotay(startTime){ var startdate = new Date((startTime).rep ...
- TensorFlow基础笔记(2) minist分类学习
(1) 最简单的神经网络分类器 # encoding: UTF-8 import tensorflow as tf from tensorflow.examples.tutorials.mnist i ...
- VS2005环境下采用makefile编译、使用libjpeg.lib函数库
1.从www.ijg.org下载源码,解压后得到文件夹jpeg-8d 2.在文件夹里新建jconfig.h文件,将jconfig.vc里的内容拷到jconfig.h中 3.编译. Run->CM ...
- 敏捷软件开发实践-Code Review Process(转)
介绍: 在敏捷软件开发中,从代码的产生速度上来看,要比 传统Waterfall产生速度高很多.因为我们把时间安排的更加紧凑了.那么这么多的代码,如何能保证这些代码质量呢?很多人可能直接想到静态代码检测 ...
- git 怎么看某个commit 修改的代码
详细的更改: git show commitid 只列出文件名:git show --pretty="format:" --name-only commitid 转自: http: ...
- VBS 移除excel数据公式,只保留值
如果将excel数据公式移除,只保留计算之后的值,将大大减少excel文件. 因为有上篇移除excel外部数据链接的经验,进行excel数据公式移除将快的多,方法如下. 首先我们得明白怎么手动移除ex ...
- loadimage1();有问题
f.Read(pBuffer, nSize)不能少,少了虽然能读进去数据但是不能显示成图片,可能原因是存进的数据并不是图片数据! 输入图片测试,但是没有CFile先Open再Read
- SQL语句:语法错误(操作符丢失)在查询表达式中
所谓操作符丢失,应该是你在拼接SQL语句是少了关键词或者分隔符,导致系统无法识别SQL语句.建议:1.监控SQL语句,看看哪里出现问题:断点看下最后的sql到底是什么样子就知道了,另外你可以把这段sq ...
- hdu 4722(记忆化搜索)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4722 思路:简单的记忆化搜索,留意一下A==0时的情况就可以了. #include<iostre ...
- HttpServletRequest和HttpServletResponse简介
http://blog.csdn.net/tong_xinglong/article/details/12972819