您的位置:首页 > 其它

Command模式,Functor与对之应用的一些想法

2010-11-01 16:51 253 查看
command模式:以对象封装命令;避免了以其他方式传递命令易错的特点(如,使用string)
最简单的command命令模式是:接受某具体command,调用相应的receiver进行处理,所进行的不过是转调。
最基本的改进是:设定某些条件,在改条件成立时,invoker才进行调用。如此可以实现:每隔多少时间进行某些操作的方法。
也可以在调用前进行某些逻辑,这就是:主动式命令(相反称之为转发式命令)
最麻烦的是,要手工编写很多的具体命令。loki中使用Functor来帮助实现。
另有:多动作之序列化,借此可实现,在某条件成立时,连续按序执行一系列特地命令。且这些命令可以单独使用。是不是以一个汇总的单独command既可以实现?

原来换肤是用命令模式来实现的?……

使用ResultType来定义functor的返回值以实现template出一系列functors,很有意思啊



在实作Functor中,我们会希望对用户来说,无论其定义多少个命令的functor,他所看到的就只有一个接口。



使用Typelist来实现不定参数。

template<typename R, class TList = NullType,
        template<class> class ThreadingModel = DEFAULT_THREADING>
    class Functor
    {
    public:
        // Handy type definitions for the body type
        typedef FunctorImpl<R, TList, ThreadingModel> Impl;
        typedef R               ResultType;
        typedef TList           ParmList;
        
        template<typename R1, class TList1>
        struct RebindParmList
        {
            typedef Functor<R1, TList1, ThreadingModel> Result;
        };

        typedef typename Impl::Parm1 Parm1;
        typedef typename Impl::Parm2 Parm2;
        typedef typename Impl::Parm3 Parm3;
        typedef typename Impl::Parm4 Parm4;
        typedef typename Impl::Parm5 Parm5;
        typedef typename Impl::Parm6 Parm6;
        typedef typename Impl::Parm7 Parm7;
        typedef typename Impl::Parm8 Parm8;
        typedef typename Impl::Parm9 Parm9;
        typedef typename Impl::Parm10 Parm10;
        typedef typename Impl::Parm11 Parm11;
        typedef typename Impl::Parm12 Parm12;
        typedef typename Impl::Parm13 Parm13;
        typedef typename Impl::Parm14 Parm14;
        typedef typename Impl::Parm15 Parm15;
}


其中,TList是个Typelist,对Typelist的解析在FunctorImpl中,FunctorImpl解析出实际的参数(使不定参数定值化),而将这些定值化的参数定义于本地。

FunctorImpl并不如我所想定义了一堆的Typedef(实际上确实是通过定义了一堆typedef来实现的,但不是在FunctorImpl中)

template 
    <
        typename R, 
        class TList, 
        template <class> class ThreadingModel = DEFAULT_THREADING
    >
    class FunctorImpl 
        : public Private::FunctorImplHelper
          <
              TL::Length<TList>::value
          >
          ::template In<R, TList, ThreadingModel>
    {
        ASSERT_TYPELIST(TList);
    };


重点注意:: public Private::FunctorImplHelper 这句,这实际上是继承了一个FunctorImplHelper,并以Typelist的长度(即实际的元素个数)为参数的template.Length定义于Typelist中。

比如,用户如此使用:

Functor<double,TYPELIST_2<int,double> >	myFunctor;


于是这里的TL::Length<TList>::value == 2,于是模板被特化到FunctorImplHelper<2>中去。

在Loki中,限定Type的个数最多只能是15。于是可以想到FunctorImplHelper至少有15个。

例如,FunctorImplHelper<2>如下:

template <>
   struct FunctorImplHelper<2>
   {
       template <typename R, class TList, template <class> class ThreadingModel>
       class In : public Private::FunctorImplBase<R, ThreadingModel>
       {
           typedef typename TL::TypeAt<TList, 0>::Result P1;
           typedef typename TL::TypeAt<TList, 1>::Result P2;

       public:
           typedef R ResultType;
           typedef typename TypeTraits<P1>::ParameterType Parm1;
           typedef typename TypeTraits<P2>::ParameterType Parm2;
           virtual R operator()(Parm1, Parm2) = 0;
       };
   };


使用了定义于 Typelist中的TypeAt来Index该2个元素的Typelist中的所有元素。但由于该TypeAt出来的仅仅是用户所给定的原始Type,所以有了使用TypeTraits的进一步处理。相应的,在每个FunctorImplHelper中都定义了其相应的operator() (由参数个数的不同,而定义了正确的operator() ,因为定义一个operator()(...)并不是一个好注意…… )



完整的FunctorImplHelper定义如下:

////////////////////////////////////////////////////////////////////////////////
// class template FunctorImplHelper
// Base template
////////////////////////////////////////////////////////////////////////////////
template <unsigned int TListLength>
struct FunctorImplHelper;

////////////////////////////////////////////////////////////////////////////////
// class template FunctorImplHelper
// Specialization for 0 (zero) parameters
////////////////////////////////////////////////////////////////////////////////

template <>
struct FunctorImplHelper<0>
{
template <typename R, class TList, template <class> class ThreadingModel>
class In : public Private::FunctorImplBase<R, ThreadingModel>
{
public:
typedef R ResultType;
virtual R operator()() = 0;
};
};

////////////////////////////////////////////////////////////////////////////////
// class template FunctorImplHelper
// Specialization for 1 parameter
////////////////////////////////////////////////////////////////////////////////

template <>
struct FunctorImplHelper<1>
{
template <typename R, class TList, template <class> class ThreadingModel>
class In : public Private::FunctorImplBase<R, ThreadingModel>
{
typedef typename TL::TypeAt<TList, 0>::Result P1;

public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
virtual R operator()(Parm1) = 0;
};
};

////////////////////////////////////////////////////////////////////////////////
// class template FunctorImplHelper
// Specialization for 2 parameters
////////////////////////////////////////////////////////////////////////////////
template <> struct FunctorImplHelper<2> { template <typename R, class TList, template <class> class ThreadingModel> class In : public Private::FunctorImplBase<R, ThreadingModel> { typedef typename TL::TypeAt<TList, 0>::Result P1; typedef typename TL::TypeAt<TList, 1>::Result P2; public: typedef R ResultType; typedef typename TypeTraits<P1>::ParameterType Parm1; typedef typename TypeTraits<P2>::ParameterType Parm2; virtual R operator()(Parm1, Parm2) = 0; }; };////////////////////////////////////////////////////////////////////////////////
// class template FunctorImplHelper
// Specialization for 3 parameters
////////////////////////////////////////////////////////////////////////////////
template <>
struct FunctorImplHelper<3>
{
template <typename R, class TList, template <class> class ThreadingModel>
class In : public Private::FunctorImplBase<R, ThreadingModel>
{
typedef typename TL::TypeAt<TList, 0>::Result P1;
typedef typename TL::TypeAt<TList, 1>::Result P2;
typedef typename TL::TypeAt<TList, 2>::Result P3;

public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
virtual R operator()(Parm1, Parm2, Parm3) = 0;
};
};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImplHelper
// Specialization for 4 parameters
////////////////////////////////////////////////////////////////////////////////
template <>
struct FunctorImplHelper<4>
{
template <typename R, class TList, template <class> class ThreadingModel>
class In : public Private::FunctorImplBase<R, ThreadingModel>
{
typedef typename TL::TypeAt<TList, 0>::Result P1;
typedef typename TL::TypeAt<TList, 1>::Result P2;
typedef typename TL::TypeAt<TList, 2>::Result P3;
typedef typename TL::TypeAt<TList, 3>::Result P4;

public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
typedef typename TypeTraits<P4>::ParameterType Parm4;
virtual R operator()(Parm1, Parm2, Parm3, Parm4) = 0;
};
};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImplHelper
// Specialization for 5 parameters
////////////////////////////////////////////////////////////////////////////////
template <>
struct FunctorImplHelper<5>
{
template <typename R, class TList, template <class> class ThreadingModel>
class In : public Private::FunctorImplBase<R, ThreadingModel>
{
typedef typename TL::TypeAt<TList, 0>::Result P1;
typedef typename TL::TypeAt<TList, 1>::Result P2;
typedef typename TL::TypeAt<TList, 2>::Result P3;
typedef typename TL::TypeAt<TList, 3>::Result P4;
typedef typename TL::TypeAt<TList, 4>::Result P5;

public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
typedef typename TypeTraits<P4>::ParameterType Parm4;
typedef typename TypeTraits<P5>::ParameterType Parm5;
virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5) = 0;
};
};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImplHelper
// Specialization for 6 parameters
////////////////////////////////////////////////////////////////////////////////
template <>
struct FunctorImplHelper<6>
{
template <typename R, class TList, template <class> class ThreadingModel>
class In : public Private::FunctorImplBase<R, ThreadingModel>
{
typedef typename TL::TypeAt<TList, 0>::Result P1;
typedef typename TL::TypeAt<TList, 1>::Result P2;
typedef typename TL::TypeAt<TList, 2>::Result P3;
typedef typename TL::TypeAt<TList, 3>::Result P4;
typedef typename TL::TypeAt<TList, 4>::Result P5;
typedef typename TL::TypeAt<TList, 5>::Result P6;

public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
typedef typename TypeTraits<P4>::ParameterType Parm4;
typedef typename TypeTraits<P5>::ParameterType Parm5;
typedef typename TypeTraits<P6>::ParameterType Parm6;
virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6) = 0;
};
};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImplHelper
// Specialization for 7 parameters
////////////////////////////////////////////////////////////////////////////////
template <>
struct FunctorImplHelper<7>
{
template <typename R, class TList, template <class> class ThreadingModel>
class In : public Private::FunctorImplBase<R, ThreadingModel>
{
typedef typename TL::TypeAt<TList, 0>::Result P1;
typedef typename TL::TypeAt<TList, 1>::Result P2;
typedef typename TL::TypeAt<TList, 2>::Result P3;
typedef typename TL::TypeAt<TList, 3>::Result P4;
typedef typename TL::TypeAt<TList, 4>::Result P5;
typedef typename TL::TypeAt<TList, 5>::Result P6;
typedef typename TL::TypeAt<TList, 6>::Result P7;

public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
typedef typename TypeTraits<P4>::ParameterType Parm4;
typedef typename TypeTraits<P5>::ParameterType Parm5;
typedef typename TypeTraits<P6>::ParameterType Parm6;
typedef typename TypeTraits<P7>::ParameterType Parm7;
virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7) = 0;
};
};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImplHelper
// Specialization for 8 parameters
////////////////////////////////////////////////////////////////////////////////
template <>
struct FunctorImplHelper<8>
{
template <typename R, class TList, template <class> class ThreadingModel>
class In : public Private::FunctorImplBase<R, ThreadingModel>
{
typedef typename TL::TypeAt<TList, 0>::Result P1;
typedef typename TL::TypeAt<TList, 1>::Result P2;
typedef typename TL::TypeAt<TList, 2>::Result P3;
typedef typename TL::TypeAt<TList, 3>::Result P4;
typedef typename TL::TypeAt<TList, 4>::Result P5;
typedef typename TL::TypeAt<TList, 5>::Result P6;
typedef typename TL::TypeAt<TList, 6>::Result P7;
typedef typename TL::TypeAt<TList, 7>::Result P8;

public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
typedef typename TypeTraits<P4>::ParameterType Parm4;
typedef typename TypeTraits<P5>::ParameterType Parm5;
typedef typename TypeTraits<P6>::ParameterType Parm6;
typedef typename TypeTraits<P7>::ParameterType Parm7;
typedef typename TypeTraits<P8>::ParameterType Parm8;
virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7, Parm8) = 0;
};
};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImplHelper
// Specialization for 9 parameters
////////////////////////////////////////////////////////////////////////////////
template <>
struct FunctorImplHelper<9>
{
template <typename R, class TList, template <class> class ThreadingModel>
class In : public Private::FunctorImplBase<R, ThreadingModel>
{
typedef typename TL::TypeAt<TList, 0>::Result P1;
typedef typename TL::TypeAt<TList, 1>::Result P2;
typedef typename TL::TypeAt<TList, 2>::Result P3;
typedef typename TL::TypeAt<TList, 3>::Result P4;
typedef typename TL::TypeAt<TList, 4>::Result P5;
typedef typename TL::TypeAt<TList, 5>::Result P6;
typedef typename TL::TypeAt<TList, 6>::Result P7;
typedef typename TL::TypeAt<TList, 7>::Result P8;
typedef typename TL::TypeAt<TList, 8>::Result P9;

public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
typedef typename TypeTraits<P4>::ParameterType Parm4;
typedef typename TypeTraits<P5>::ParameterType Parm5;
typedef typename TypeTraits<P6>::ParameterType Parm6;
typedef typename TypeTraits<P7>::ParameterType Parm7;
typedef typename TypeTraits<P8>::ParameterType Parm8;
typedef typename TypeTraits<P9>::ParameterType Parm9;
virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7, Parm8, Parm9) = 0;
};
};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImplHelper
// Specialization for 10 parameters
////////////////////////////////////////////////////////////////////////////////
template <>
struct FunctorImplHelper<10>
{
template <typename R, class TList, template <class> class ThreadingModel>
class In : public Private::FunctorImplBase<R, ThreadingModel>
{
typedef typename TL::TypeAt<TList, 0>::Result P1;
typedef typename TL::TypeAt<TList, 1>::Result P2;
typedef typename TL::TypeAt<TList, 2>::Result P3;
typedef typename TL::TypeAt<TList, 3>::Result P4;
typedef typename TL::TypeAt<TList, 4>::Result P5;
typedef typename TL::TypeAt<TList, 5>::Result P6;
typedef typename TL::TypeAt<TList, 6>::Result P7;
typedef typename TL::TypeAt<TList, 7>::Result P8;
typedef typename TL::TypeAt<TList, 8>::Result P9;
typedef typename TL::TypeAt<TList, 9>::Result P10;

public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
typedef typename TypeTraits<P4>::ParameterType Parm4;
typedef typename TypeTraits<P5>::ParameterType Parm5;
typedef typename TypeTraits<P6>::ParameterType Parm6;
typedef typename TypeTraits<P7>::ParameterType Parm7;
typedef typename TypeTraits<P8>::ParameterType Parm8;
typedef typename TypeTraits<P9>::ParameterType Parm9;
typedef typename TypeTraits<P10>::ParameterType Parm10;
virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7, Parm8, Parm9, Parm10) = 0;
};
};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImplHelper
// Specialization for 11 parameters
////////////////////////////////////////////////////////////////////////////////
template <>
struct FunctorImplHelper<11>
{
template <typename R, class TList, template <class> class ThreadingModel>
class In : public Private::FunctorImplBase<R, ThreadingModel>
{
typedef typename TL::TypeAt<TList, 0>::Result P1;
typedef typename TL::TypeAt<TList, 1>::Result P2;
typedef typename TL::TypeAt<TList, 2>::Result P3;
typedef typename TL::TypeAt<TList, 3>::Result P4;
typedef typename TL::TypeAt<TList, 4>::Result P5;
typedef typename TL::TypeAt<TList, 5>::Result P6;
typedef typename TL::TypeAt<TList, 6>::Result P7;
typedef typename TL::TypeAt<TList, 7>::Result P8;
typedef typename TL::TypeAt<TList, 8>::Result P9;
typedef typename TL::TypeAt<TList, 9>::Result P10;
typedef typename TL::TypeAt<TList, 10>::Result P11;

public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
typedef typename TypeTraits<P4>::ParameterType Parm4;
typedef typename TypeTraits<P5>::ParameterType Parm5;
typedef typename TypeTraits<P6>::ParameterType Parm6;
typedef typename TypeTraits<P7>::ParameterType Parm7;
typedef typename TypeTraits<P8>::ParameterType Parm8;
typedef typename TypeTraits<P9>::ParameterType Parm9;
typedef typename TypeTraits<P10>::ParameterType Parm10;
typedef typename TypeTraits<P11>::ParameterType Parm11;
virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7, Parm8, Parm9, Parm10, Parm11) = 0;
};
};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImplHelper
// Specialization for 12 parameters
////////////////////////////////////////////////////////////////////////////////
template <>
struct FunctorImplHelper<12>
{
template <typename R, class TList, template <class> class ThreadingModel>
class In : public Private::FunctorImplBase<R, ThreadingModel>
{
typedef typename TL::TypeAt<TList, 0>::Result P1;
typedef typename TL::TypeAt<TList, 1>::Result P2;
typedef typename TL::TypeAt<TList, 2>::Result P3;
typedef typename TL::TypeAt<TList, 3>::Result P4;
typedef typename TL::TypeAt<TList, 4>::Result P5;
typedef typename TL::TypeAt<TList, 5>::Result P6;
typedef typename TL::TypeAt<TList, 6>::Result P7;
typedef typename TL::TypeAt<TList, 7>::Result P8;
typedef typename TL::TypeAt<TList, 8>::Result P9;
typedef typename TL::TypeAt<TList, 9>::Result P10;
typedef typename TL::TypeAt<TList, 10>::Result P11;
typedef typename TL::TypeAt<TList, 11>::Result P12;

public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
typedef typename TypeTraits<P4>::ParameterType Parm4;
typedef typename TypeTraits<P5>::ParameterType Parm5;
typedef typename TypeTraits<P6>::ParameterType Parm6;
typedef typename TypeTraits<P7>::ParameterType Parm7;
typedef typename TypeTraits<P8>::ParameterType Parm8;
typedef typename TypeTraits<P9>::ParameterType Parm9;
typedef typename TypeTraits<P10>::ParameterType Parm10;
typedef typename TypeTraits<P11>::ParameterType Parm11;
typedef typename TypeTraits<P12>::ParameterType Parm12;
virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7, Parm8, Parm9, Parm10, Parm11, Parm12) = 0;
};
};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImplHelper
// Specialization for 13 parameters
////////////////////////////////////////////////////////////////////////////////
template <>
struct FunctorImplHelper<13>
{
template <typename R, class TList, template <class> class ThreadingModel>
class In : public Private::FunctorImplBase<R, ThreadingModel>
{
typedef typename TL::TypeAt<TList, 0>::Result P1;
typedef typename TL::TypeAt<TList, 1>::Result P2;
typedef typename TL::TypeAt<TList, 2>::Result P3;
typedef typename TL::TypeAt<TList, 3>::Result P4;
typedef typename TL::TypeAt<TList, 4>::Result P5;
typedef typename TL::TypeAt<TList, 5>::Result P6;
typedef typename TL::TypeAt<TList, 6>::Result P7;
typedef typename TL::TypeAt<TList, 7>::Result P8;
typedef typename TL::TypeAt<TList, 8>::Result P9;
typedef typename TL::TypeAt<TList, 9>::Result P10;
typedef typename TL::TypeAt<TList, 10>::Result P11;
typedef typename TL::TypeAt<TList, 11>::Result P12;
typedef typename TL::TypeAt<TList, 12>::Result P13;

public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
typedef typename TypeTraits<P4>::ParameterType Parm4;
typedef typename TypeTraits<P5>::ParameterType Parm5;
typedef typename TypeTraits<P6>::ParameterType Parm6;
typedef typename TypeTraits<P7>::ParameterType Parm7;
typedef typename TypeTraits<P8>::ParameterType Parm8;
typedef typename TypeTraits<P9>::ParameterType Parm9;
typedef typename TypeTraits<P10>::ParameterType Parm10;
typedef typename TypeTraits<P11>::ParameterType Parm11;
typedef typename TypeTraits<P12>::ParameterType Parm12;
typedef typename TypeTraits<P13>::ParameterType Parm13;
virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13) = 0;
};
};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImplHelper
// Specialization for 14 parameters
////////////////////////////////////////////////////////////////////////////////
template <>
struct FunctorImplHelper<14>
{
template <typename R, class TList, template <class> class ThreadingModel>
class In : public Private::FunctorImplBase<R, ThreadingModel>
{
typedef typename TL::TypeAt<TList, 0>::Result P1;
typedef typename TL::TypeAt<TList, 1>::Result P2;
typedef typename TL::TypeAt<TList, 2>::Result P3;
typedef typename TL::TypeAt<TList, 3>::Result P4;
typedef typename TL::TypeAt<TList, 4>::Result P5;
typedef typename TL::TypeAt<TList, 5>::Result P6;
typedef typename TL::TypeAt<TList, 6>::Result P7;
typedef typename TL::TypeAt<TList, 7>::Result P8;
typedef typename TL::TypeAt<TList, 8>::Result P9;
typedef typename TL::TypeAt<TList, 9>::Result P10;
typedef typename TL::TypeAt<TList, 10>::Result P11;
typedef typename TL::TypeAt<TList, 11>::Result P12;
typedef typename TL::TypeAt<TList, 12>::Result P13;
typedef typename TL::TypeAt<TList, 13>::Result P14;

public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
typedef typename TypeTraits<P4>::ParameterType Parm4;
typedef typename TypeTraits<P5>::ParameterType Parm5;
typedef typename TypeTraits<P6>::ParameterType Parm6;
typedef typename TypeTraits<P7>::ParameterType Parm7;
typedef typename TypeTraits<P8>::ParameterType Parm8;
typedef typename TypeTraits<P9>::ParameterType Parm9;
typedef typename TypeTraits<P10>::ParameterType Parm10;
typedef typename TypeTraits<P11>::ParameterType Parm11;
typedef typename TypeTraits<P12>::ParameterType Parm12;
typedef typename TypeTraits<P13>::ParameterType Parm13;
typedef typename TypeTraits<P14>::ParameterType Parm14;
virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13, Parm14) = 0;
};
};
////////////////////////////////////////////////////////////////////////////////
// class template FunctorImplHelper
// Specialization for 15 parameters
////////////////////////////////////////////////////////////////////////////////
template <>
struct FunctorImplHelper<15>
{
template <typename R, class TList, template <class> class ThreadingModel>
class In : public Private::FunctorImplBase<R, ThreadingModel>
{
typedef typename TL::TypeAt<TList, 0>::Result P1;
typedef typename TL::TypeAt<TList, 1>::Result P2;
typedef typename TL::TypeAt<TList, 2>::Result P3;
typedef typename TL::TypeAt<TList, 3>::Result P4;
typedef typename TL::TypeAt<TList, 4>::Result P5;
typedef typename TL::TypeAt<TList, 5>::Result P6;
typedef typename TL::TypeAt<TList, 6>::Result P7;
typedef typename TL::TypeAt<TList, 7>::Result P8;
typedef typename TL::TypeAt<TList, 8>::Result P9;
typedef typename TL::TypeAt<TList, 9>::Result P10;
typedef typename TL::TypeAt<TList, 10>::Result P11;
typedef typename TL::TypeAt<TList, 11>::Result P12;
typedef typename TL::TypeAt<TList, 12>::Result P13;
typedef typename TL::TypeAt<TList, 13>::Result P14;
typedef typename TL::TypeAt<TList, 14>::Result P15;

public:
typedef R ResultType;
typedef typename TypeTraits<P1>::ParameterType Parm1;
typedef typename TypeTraits<P2>::ParameterType Parm2;
typedef typename TypeTraits<P3>::ParameterType Parm3;
typedef typename TypeTraits<P4>::ParameterType Parm4;
typedef typename TypeTraits<P5>::ParameterType Parm5;
typedef typename TypeTraits<P6>::ParameterType Parm6;
typedef typename TypeTraits<P7>::ParameterType Parm7;
typedef typename TypeTraits<P8>::ParameterType Parm8;
typedef typename TypeTraits<P9>::ParameterType Parm9;
typedef typename TypeTraits<P10>::ParameterType Parm10;
typedef typename TypeTraits<P11>::ParameterType Parm11;
typedef typename TypeTraits<P12>::ParameterType Parm12;
typedef typename TypeTraits<P13>::ParameterType Parm13;
typedef typename TypeTraits<P14>::ParameterType Parm14;
typedef typename TypeTraits<P15>::ParameterType Parm15;
virtual R operator()(Parm1, Parm2, Parm3, Parm4, Parm5, Parm6, Parm7, Parm8, Parm9, Parm10, Parm11, Parm12, Parm13, Parm14, Parm15) = 0;
};
};




在FunctorImpl中,对FunctorImplHelper的使用颇有意思。使FunctorImpl实作出FunctorImplHelper 的仅仅是: public Private::FunctorImplHelper,仅仅是这个继承而已,而完成对Parm的定义则是通过: public Private::FunctorImplHelper后的::template In<R, TList, ThreadingModel>来完成的,Parm是通过对template In的继承而来的。

因此,在class Functor中可以如下定义class Functor将使用到的各型别:

typedef typename Impl::Parm1 Parm1;
        typedef typename Impl::Parm2 Parm2;
        typedef typename Impl::Parm3 Parm3;
        typedef typename Impl::Parm4 Parm4;
        typedef typename Impl::Parm5 Parm5;
        typedef typename Impl::Parm6 Parm6;
        typedef typename Impl::Parm7 Parm7;
        typedef typename Impl::Parm8 Parm8;
        typedef typename Impl::Parm9 Parm9;
        typedef typename Impl::Parm10 Parm10;
        typedef typename Impl::Parm11 Parm11;
        typedef typename Impl::Parm12 Parm12;
        typedef typename Impl::Parm13 Parm13;
        typedef typename Impl::Parm14 Parm14;
        typedef typename Impl::Parm15 Parm15;




以上实际上进行的是:class组合+模板偏特化。



Functor使用IMPL手法来实现相应的具体操作。

private:

        // VC7 can't see the defined ctor when the template version in present
        struct Helper
        {
            Helper()
                : spImpl_(0)
            {}

            Helper(const Helper &rhs)
                : spImpl_(Impl::Clone(rhs.spImpl_.get()))
            {}

            explicit Helper(std::auto_ptr<Impl> spImpl)
                : spImpl_(spImpl)
            {}

            template<typename U>
            explicit Helper(U *ptr)
                : spImpl_(ptr)
            {}

            Impl& operator*() const
            {
                return *spImpl_;
            }

        public:
            std::auto_ptr<Impl> spImpl_;
        };

        Helper spImpl_;


spImpl_ 是一个Private变量,因此对之访问仅限于class内部。

spImpl_定义为:std::auto_ptr<Impl> spImpl_; 在使用中,将指向具体的FunctorImpl<R, TList, ThreadingModel>

于是,在class Functor内,我们可以很方便的写出以下代码:



Functor() : spImpl_()
        {}
        
        
#if 0 // The Helper class will do those constructions because of VC7 bug
        Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get()))
        {}
#endif        

        Functor(std::auto_ptr<Impl> spImpl) : spImpl_(spImpl)
        {}


以上是构造函数。可以看到,最终使用了struct Helper的构造函数。

注意:spImpl_是一个指向具体的FunctorImpl<R, TList, ThreadingModel>的智能指针,R是用户给定的。而FunctorImpl中,由FunctorImplHelper重载了operator(),FunctorImpl将之继承至了自己的public,因此,对这些重载了operator()的class,我们可以直接调用之,这就是仿函数。当我们直接调用这些对象时,编译器会适当的进行这些对象所重载的operator()的调用。

如此,一路继承到class Functor中后,我们就可以写出这样的调用代码:



ResultType operator()()
        { return (*spImpl_)(); }

        ResultType operator()(Parm1 p1)
        { return (*spImpl_)(p1); }
        
        ResultType operator()(Parm1 p1, Parm2 p2)
        { return (*spImpl_)(p1, p2); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
        { return (*spImpl_)(p1, p2, p3); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
        { return (*spImpl_)(p1, p2, p3, p4); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
        { return (*spImpl_)(p1, p2, p3, p4, p5); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6)
        { return (*spImpl_)(p1, p2, p3, p4, p5, p6); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7)
        { return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7, Parm8 p8)
        { return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
        { return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
        { return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
        { return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
            Parm12 p12)
        {
            return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, 
                p12);
        }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
            Parm12 p12, Parm13 p13)
        {
            return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11,
            p12, p13);
        }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
            Parm12 p12, Parm13 p13, Parm14 p14)
        {
            return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, 
                p12, p13, p14);
        }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
            Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
        {
            return (*spImpl_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, 
                p12, p13, p14, p15);
        }


*spImpl_ 会调用到struct Helper中的operator*,该operator*返回一个指向具体FunctorImpl的智能指针,该FunctorImpl是一个仿函数,于是自然调用到定义于FunctorImpl中的,已具体化参数的operator()

但实际上,C++不允许同名,但参数个数不同的templates,因此这么多的operator()是错误的。但实际这些是能编译通过的,因为在一次使用中,我们最终会选定某个operator(),因此只会使用到某个operator(),因此编译器只编译其中的一个operator()



接下来要进行的是处理仿函数。



首先,Functor本身是仿函数,因其定义了operator(),因此,Functor应该有一个构造函数,接受某仿函数完成构造。

如下:

template <typename Fun>
        Functor(Fun fun)
        : spImpl_(new FunctorHandler<Functor, Fun>(fun))
        {}




ParentFunctor 的定义是:Wraps functors and pointers to functions,其实现为:

template <class ParentFunctor, typename Fun>
    class FunctorHandler
        : public ParentFunctor::Impl
    {
        typedef typename ParentFunctor::Impl Base;

    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) {}
        
        DEFINE_CLONE_FUNCTORIMPL(FunctorHandler)

        // 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); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
        { return f_(p1, p2, p3, p4); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
        { return f_(p1, p2, p3, p4, p5); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6)
        { return f_(p1, p2, p3, p4, p5, p6); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7)
        { return f_(p1, p2, p3, p4, p5, p6, p7); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7, Parm8 p8)
        { return f_(p1, p2, p3, p4, p5, p6, p7, p8); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
        { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
        { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
        { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
            Parm12 p12)
        { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
            Parm12 p12, Parm13 p13)
        { return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
            Parm12 p12, Parm13 p13, Parm14 p14)
        {
            return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, 
                p14);
        }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
            Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
        {
            return f_(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, 
                p14, p15);
        }
        
    private:
        Fun f_;
    };


有没有觉得很神奇,突然出现了一个class ParentFuncto,且在实作中使用了typedef typename ParentFunctor::Impl Base;及一系列关于Base::Parm的typedefs。但请注意,ParentFunctor仅仅是template 的一个参数 class ParentFunctor,即是,在使用FunctorHandler时由用户传递的参数。而我们在使用FunctorHandler时,是这样的:

spImpl_(new FunctorHandler<Functor, Fun>(fun))


因此,这里的 ParentFuncto实际上是:Functor,而Functor 是class Functor自身。这里的整个构造是:FunctorHandler中的FunctorHandler(const Fun& fun) : f_(fun) {}完成的。

这里的意思是:“以仿函数Fun之对象为参数的Functor构造函数”,只不过这里的Functor是其自身而已。

实际上,这里所要完成的是:以某一个用户给定的仿函数来完成Functor class的构造。Functor(Fun fun)中给定的Fun是typename,而fun,是具体的仿函数。于是,从Functor的该构造函数出发,通过new FunctorHandler<Functor, Fun>(fun) 实作出了一系列的operator(),这些operator()以确定的参数,调用用户所给仿函数中所重载的operator()。

这就是故事的全部。



在这之前的:

Functor<double,TYPELIST_2<int,double> >	myFunctor;


使用的是:emplate<typename R, class TList = NullType,
template<class> class ThreadingModel = DEFAULT_THREADING>

这用于class template Funtor的构造。而现在的template <typename Fun>则作为构造函数的参数。

这里所做的事是:构造函数的函数本体对spImpl_成员进行初始化,使之指向一个型别为FunctorHandler的新对象,该对象系通过适当参数被具现化和初始化的。

可以看到spImpl_的定义是:Helper spImpl_; 因此这里在以所new的FunctorHandler指针来构造Helper,构造Helper所使用的函数是:

template<typename U>
            explicit Helper(U *ptr)
                : spImpl_(ptr)
            {}


对此,我们可以写个测试程序如下:



测试1.

#include "Functor.h"
#include <iostream>

using namespace std;

// define a functor
struct TestFunctor
{
	void operator() (int i, double d)
	{
		cout<<"TestFunctor::operator() ("<<i<<","<<d<< ")" called./n";
	}
};

int main()
{
	TestFunctor f;									// 1.
	Functor<void,TYPELIST_2(int,double)> cmd(f);	// 2.
	cmd(4,4.5);										// 3.
}


1.定义了一个仿函数(重载了operator())

2.定义template Functor实例 cmd。其中使用了上述的构造函数。

3.调用实例cmd的operator(),该operator()调用会自动调用至TestFunctor中的operator()



在测试1中,我们显示的定义了一个TestFunctor实例,再用它来实例化template functor。

也可以直接使用一个函数进行,如下:



测试2:

void TestFunction(int i, double d)
{
	cout<<"TestFunction ("<<i<<","<<d<< ")" called./n";
}

int main()
{
	// TestFunctor f;										// 1.
	Functor<void,TYPELIST_2(int,double)> cmd(TestFunctor);	// 2.
	cmd(4,4.5);												// 3.
}


但,如果出现了TestFunction的重载版本,那么编译器会报错。解决办法可以是:定义函数指针并使用之;在使用时进行型别转换。具体不再详述。



可能比较麻烦的是成员函数指针。实际上,成员函数指针并不常用。

在Loki中,提供了MemFunHandler指向成员函数。



其定义如下:

template <class ParentFunctor, typename PointerToObj,
        typename PointerToMemFn>
    class MemFunHandler : public ParentFunctor::Impl
    {
    };


在Functor中存在对其调用:

template <class PtrObj, typename MemFn>
        Functor(const PtrObj& p, MemFn memFn)
        : spImpl_(new MemFunHandler<Functor, PtrObj, MemFn>(p, memFn))
        {}


PtrObj是外部传来的某对象实例的指针,memFn是外部来的某成员函数的指针。(别忘了,对对象成员的函数的函数指针形式调用需要同时使用对象实例和函数指针。)

因此,在MemFunHandler中,以下代码就不难理解了。

template <class ParentFunctor, typename PointerToObj,
        typename PointerToMemFn>
    class MemFunHandler : public ParentFunctor::Impl
    {
        typedef typename ParentFunctor::Impl Base;

    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;

        MemFunHandler(const PointerToObj& pObj, PointerToMemFn pMemFn) 
        : pObj_(pObj), pMemFn_(pMemFn)
        {}

        ResultType operator()()
        { return ((*pObj_).*pMemFn_)(); }

        ResultType operator()(Parm1 p1)
        { return ((*pObj_).*pMemFn_)(p1); }
        
        ResultType operator()(Parm1 p1, Parm2 p2)
        { return ((*pObj_).*pMemFn_)(p1, p2); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3)
        { return ((*pObj_).*pMemFn_)(p1, p2, p3); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4)
        { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5)
        { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6)
        { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7)
        { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7, Parm8 p8)
        { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9)
        { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10)
        { return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11)
        {
            return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, 
                p11);
        }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
            Parm12 p12)
        {
            return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, 
                p11, p12);
        }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
            Parm12 p12, Parm13 p13)
        {
            return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, 
                p11, p12, p13);
        }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
            Parm12 p12, Parm13 p13, Parm14 p14)
        {
            return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, 
                p11, p12, p13, p14);
        }
        
        ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5,
            Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, Parm11 p11,
            Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15)
        {
            return ((*pObj_).*pMemFn_)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, 
                p11, p12, p13, p14, p15);
        }
        
    private:
        PointerToObj pObj_;
        PointerToMemFn pMemFn_;
    };


无非是typedef 参数,转调成员函数等动作。

这里template参数中typename PointerToObj, 是一个指向对象的指针,之所以不直接使用typename Obj,是因为需要更大的泛用。



自己写完后,好好的反思了下。写了这么多,只不过是在剖析别人的源代码而已。这样的技术很炫,但这似乎也只是语言技术上的炫目。对一个软件开发人员来说,什么才是最重要的?我想绝不是也不应该是语言的炫目技术。

似乎自己一直以来都太沉迷于语言细节,仿佛什么东西最晦涩,那搞懂什么就越有成就感……



我们应该更关注什么?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: