0

最近我根据“Modern C++ design”一书制作了两个模板类。我认为这些课程很有用,但我公司里没有人同意我的观点,那么有人能告诉我这些东西是否有用吗?

第一个是参数包装器,它可以将函数参数包装到单个动态对象中。它看起来像“现代C++设计”中的TypeList。

你可以像这样使用它:

您的代码的某个地方:

int i = 7;
bool b = true;
double d = 3.3;
CParam *p1 = CreateParam(b,i);
CParam *p2 = CreateParam(i,b,d);

您的代码的其他地方:

int i = 0;
bool b = false;
double d = 0.0;
GetParam(p1,b,i);
GetParam(p2,i,b,d);

第二个是通用回调包装器,它与其他包装器相比有一些特别之处:
1.这个模板类有一个动态基类,它可以让你使用一个单一类型的对象来代表所有的包装器对象。
2.它可以将回调和它的参数一起包装,你可以稍后执行回调和参数。

你可以像这样使用它:

您的代码的某处:

void Test1(int i)
{
}

void Test2(bool b,int i)
{
}

CallbackFunc * p1 = CreateCallback(Test1,3);
CallbackFunc * p2 = CreateCallback(Test2,false,99);

您的代码的其他地方:

p1->Excute();
p2->Excute();  

以下是部分代码:

参数包装器:

class NullType;    
struct CParam
{
    virtual ~CParam(){}
};

template<class T1,class T2>
struct CParam2 : public CParam
{
    CParam2(T1 &t1,T2 &t2):v1(t1),v2(t2){}
    CParam2(){}
    T1 v1;
    T2 v2;
};

template<class T1>
struct CParam2<T1,NullType> : public CParam
{
    CParam2(T1 &t1):v1(t1){}
    CParam2(){}
    T1 v1;
};

template<class T1>
CParam * CreateParam(T1 t1)
{
    return (new CParam2<T1,NullType>(t1));
}

template<class T1,class T2>
CParam * CreateParam(T1 t1,T2 t2)
{
    return (new CParam2<T1,T2>(t1,t2));
}
template<class T1,class T2,class T3>
CParam * CreateParam(T1 t1,T2 t2,T3 t3)
{
    CParam2<T2,T3> t(t2,t3);
    return new CParam2<T1,CParam2<T2,T3> >(t1,t);
}

template<class T1>
void GetParam(CParam *p,T1 &t1)
{
    PARAM1(T1)* p2 = dynamic_cast<CParam2<T1,NullType>*>(p);
    t1 = p2->v1;
}

回调包装器:

#define PARAM1(T1) CParam2<T1,NullType>
#define PARAM2(T1,T2) CParam2<T1,T2>
#define PARAM3(T1,T2,T3) CParam2<T1,CParam2<T2,T3> >    

class CallbackFunc
{
public:
    virtual ~CallbackFunc(){}
    virtual void Excute(void){}
};

template<class T>
class CallbackFunc2 : public CallbackFunc
{
public:
    CallbackFunc2():m_b(false){}
    CallbackFunc2(T &t):m_t(t),m_b(true){}
    T m_t;
    bool m_b;
};


template<class M,class T>
class StaticCallbackFunc : public CallbackFunc2<T>
{
public:
    StaticCallbackFunc(M m):m_m(m){}

    StaticCallbackFunc(M m,T t):CallbackFunc2<T>(t),m_m(m){}

    virtual void Excute(void){assert(CallbackFunc2<T>::m_b);CallMethod(CallbackFunc2<T>::m_t);}

private:
    template<class T1>
    void CallMethod(PARAM1(T1) &t){m_m(t.v1);}

    template<class T1,class T2>
    void CallMethod(PARAM2(T1,T2) &t){m_m(t.v1,t.v2);}

    template<class T1,class T2,class T3>
    void CallMethod(PARAM3(T1,T2,T3) &t){m_m(t.v1,t.v2.v1,t.v2.v2);}

private:
    M m_m;
};


template<class M>
class StaticCallbackFunc<M,void> : public CallbackFunc
{
public:
    StaticCallbackFunc(M method):m_m(method){}
    virtual void Excute(void){m_m();}
private:
    M m_m;
};

template<class C,class M,class T>
class MemberCallbackFunc : public CallbackFunc2<T>
{
public:
    MemberCallbackFunc(C *pC,M m):m_pC(pC),m_m(m){}

    MemberCallbackFunc(C *pC,M m,T t):CallbackFunc2<T>(t),m_pC(pC),m_m(m){}

    virtual void Excute(void){assert(CallbackFunc2<T>::m_b);CallMethod(CallbackFunc2<T>::m_t);}

    template<class T1>
    void CallMethod(PARAM1(T1) &t){(m_pC->*m_m)(t.v1);}

    template<class T1,class T2>
    void CallMethod(PARAM2(T1,T2) &t){(m_pC->*m_m)(t.v1,t.v2);}

    template<class T1,class T2,class T3>
    void CallMethod(PARAM3(T1,T2,T3) &t){(m_pC->*m_m)(t.v1,t.v2.v1,t.v2.v2);}

private:
    C *m_pC;
    M m_m;
};


template<class T1>
CallbackFunc *CreateCallback(CallbackFunc *p,T1 t1)
{
    CParam2<T1,NullType> t(t1);
    return new StaticCallbackFunc<CallbackFunc *,CParam2<T1,NullType> >(p,t);
}

template<class C,class T1>
CallbackFunc *CreateCallback(C *pC,void(C::*pF)(T1),T1 t1)
{
    CParam2<T1,NullType>t(t1);
    return new MemberCallbackFunc<C,void(C::*)(T1),CParam2<T1,NullType> >(pC,pF,t);
}

template<class T1>
CParam2<T1,NullType> CreateCallbackParam(T1 t1)
{
    return  CParam2<T1,NullType>(t1);
}

template<class T1>
void ExcuteCallback(CallbackFunc *p,T1 t1)
{
    CallbackFunc2<CParam2<T1,NullType> > *p2 = dynamic_cast<CallbackFunc2<CParam2<T1,NullType> > *>(p);
    p2->m_t.v1 = t1;
    p2->m_b = true;
    p->Excute();
}
4

1 回答 1

0

它们看起来对我有用。在标准库中,有 std::tuple 和 std::function 做类似的事情。

所以,如果在标准库中有这样的东西值得,很多其他人可能认为能够使用包装器启用的模式编写代码很有用。

于 2012-06-18T15:18:35.027 回答