• 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调用用户传递进来的函数指针或者仿函数

    暂时写到这,后期完善

  • 相关阅读:
    shell中使用echo命令改变输出显示样式
    Shell脚本报错unary operator expected
    shell运行报 too many arguments错误
    写shell,运行出错:syntax error near unexpected token `$’do ”
    shell 脚本执行,出现错误bad interpreter: No such file or directory
    Linux 基本命令学习笔记
    如何运行 O’Reilly 书 Python for Finance 的源代码
    IntelliJ 中配置 Anaconda
    Windows 10 中安装 Anaconda 3
    Windows 中安装的 Python 如何卸载
  • 原文地址:https://www.cnblogs.com/UnGeek/p/4063571.html
Copyright © 2020-2023  润新知