第五章(泛化仿函数)

该章节有点类似于实现了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实现的较好了,没有深入再看下去了



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值