0

最近、本「Modern C++ design」に従って、2 つのテンプレート クラスを作成しました。これらのクラスは便利だと思いますが、私の会社の誰も私に同意しません。

1 つ目はパラメーター ラッパーで、関数パラメーターを単一の動的オブジェクトにパッケージ化できます。「モダン 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);

2 つ目は一般的なコールバック ラッパーで、他のラッパーと比較していくつかの特別な点
があります。
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