该章节有点类似于实现了function和bind操作
Functor.h的实现
#pragma once
#include "FunctorImpl.h"
#include "FunctorHandler.h"
// R即返回值,TList即参数列表
template<typename R, typename TList = NullType> //默认不带参数
class CFunctor
{
public:
typedef CFunctorImpl<R, TList> Impl;
typedef TList ParmList;
typedef R ResultType;
CFunctor(){};
CFunctor(const CFunctor&){};
CFunctor& operator = (const CFunctor&){return *this;};
~CFunctor(){};
explicit CFunctor(Impl* pImpl);
// 此处不能用TypeAt,因为TypeList可能只有1个甚至0个对象,如果使用TypeAt会编译不通过的。
// typedef typename TypeAt<TList, 0>::Result Param1;
//typedef typename TypeAt<TList, 1>::Result Param2;
typedef typename TypeAtNonStrict<TList, 0>::Result Param1;
typedef typename TypeAtNonStrict<TList, 1>::Result Param2;
// 仿函数
R operator()()
{
return (*pImpl_)();
}
R operator ()(Param1 p1)
{
return (*pImpl_)(p1);
}
R operator ()(Param1 p1, Param2 p2)
{
return (*pImpl_)(p1, p2);
}
template<class Fun>
CFunctor(const Fun& fun)
: pImpl_(new CFunctorHandler<CFunctor, Fun>(fun))
{
}
private:
Impl* pImpl_;
};
FunctorHandler.h的实现
#pragma once
#include "FunctorImpl.h"
template<typename ParentFunctor, typename Fun>
class CFunctorHandler: public CFunctorImpl<typename ParentFunctor::ResultType, typename ParentFunctor::ParmList>
{
public:
typedef typename ParentFunctor::ResultType ResultType;
CFunctorHandler(const Fun& fun)
: fun_(fun)
{
}
virtual CFunctorImpl* Clone() const{return new CFunctorHandler(*this);}
ResultType operator()(){return fun_();}
ResultType operator()(typename ParentFunctor::Param1 p1){return fun_(p1);}
ResultType operator()(typename ParentFunctor::Param1 p1, typename ParentFunctor::Param2 p2){return fun_(p1, p2);}
private:
Fun fun_;
};
FunctorImpl.h的实现,利用了前面的typelist
#pragma once
#include "../TypeLists/TypeList.h"
template<typename R, typename TList>
class CFunctorImpl;
template<typename R>
class CFunctorImpl<R, NullType>
{
public:
virtual R operator()() = 0;
virtual CFunctorImpl* Clone() const = 0;
virtual ~CFunctorImpl(){}
};
template<typename R, typename P1>
class CFunctorImpl<R, TYPELIST_1(P1)>
{
public:
virtual R operator()(P1) = 0;
virtual CFunctorImpl* Clone() const = 0;
virtual ~CFunctorImpl(){}
};
template<typename R, typename P1, typename P2>
class CFunctorImpl<R, TYPELIST_2(P1, P2)>
{
public:
virtual R operator()(P1, P2) = 0;
virtual CFunctorImpl* Clone() const = 0;
virtual ~CFunctorImpl(){}
};
简单的一个测试
struct Test2
{
void operator()(int i, double d)
{
cout<<"test2 i: "<<i<<", d: "<<d<<endl;
}
// 增加一个不带参数的仿函数
void operator()()
{
cout<<"test2 i: "<<", d: "<<endl;
}
};
void CTestFunctor::Test()
{
// 全局函数的仿函数
Test2 test2;
CFunctor<void, TYPELIST_2(int, double)> cmd(test2);
cmd(2, 2.5);
CFunctor<void> cmdNullParam(test2);
cmdNullParam();
}
成员函数的仿函数如何实现呢?
先来看下神秘的成员函数
class CTestFunctor
{
public:
void Test();
private:
void TestMemFun(int i);
void TestMemFun();
public:
int i_;
};
void CTestFunctor::Test()
{
// 全局函数的仿函数
Test2 test2;
CFunctor<void, TYPELIST_2(int, double)> cmd(test2);
cmd(2, 2.5);
CFunctor<void> cmdNullParam(test2);
cmdNullParam();
// 成员函数的调用方法,成员函数并不神秘
typedef void (CTestFunctor::* MemFunParam)(int);
typedef void (CTestFunctor::* MemFunNoParam)();
MemFunNoParam pactiveNoParam = &CTestFunctor::TestMemFun;
MemFunParam pactiveParam= &CTestFunctor::TestMemFun;
CTestFunctor aa;
aa.i_ = 10;
(aa.*pactiveParam)(i_);
i_ = 100;
CTestFunctor* pA= this;
(pA->*pactiveParam)(i_);
}
会发现成员函数的调用其实也很简单的,也可以把成员函数的地址取出来,保存下来进行调用
如下是成员函数的仿函数实现
//
// 成员函数的仿函数实现
template<class ParentFunctor, typename PointerToObj, typename PointerToMemFn>
class MemFunHandler: public CFunctorImpl<typename ParentFunctor::ResultType, typename ParentFunctor::ParmList>
{
public:
typedef typename ParentFunctor::ResultType ResultType;
explicit MemFunHandler(const PointerToObj& pObj, PointerToMemFn pMemFn)
:pObj_(pObj),
pMemFn_(pMemFn)
{
}
virtual MemFunHandler* Clone() const{return new MemFunHandler(*this);}
// 仿函数
ResultType operator()()
{
return ((pObj_).*pMemFn_)();
}
ResultType operator()(typename ParentFunctor::Param1 p1)
{
return ((pObj_).*pMemFn_)(p1);
}
ResultType operator()(typename ParentFunctor::Param1 p1, typename ParentFunctor::Param2 p2)
{
return ((pObj_).*pMemFn_)(p1, p2);
}
private:
PointerToObj pObj_;
PointerToMemFn pMemFn_;
};
测试代码,test接口中最后一行
void CTestFunctor::Test()
{
// 全局函数的仿函数
Test2 test2;
CFunctor<void, TYPELIST_2(int, double)> cmd(test2);
cmd(2, 2.5);
CFunctor<void> cmdNullParam(test2);
cmdNullParam();
// 成员函数的调用方法,成员函数并不神秘
typedef void (CTestFunctor::* MemFunParam)(int);
typedef void (CTestFunctor::* MemFunNoParam)();
MemFunNoParam pactiveNoParam = &CTestFunctor::TestMemFun;
MemFunParam pactiveParam= &CTestFunctor::TestMemFun;
CTestFunctor aa;
aa.i_ = 10;
(aa.*pactiveParam)(i_);
i_ = 100;
CTestFunctor* pA= this;
(pA->*pactiveParam)(i_);
MemFunHandler<CFunctor<void, TYPELIST_1(int) >, CTestFunctor, MemFunParam> cmdMemFun(aa, &CTestFunctor::TestMemFun);
cmdMemFun(i_);
}
bind的实现没有研究,考虑到C++ 11和boost均对bind实现的较好了,没有深入再看下去了