0

Recently i made two template classes,according to the book "Modern C++ design". I think these classes are useful but no one in my company agree with me,so could any one tell me if these things are useful?

The first one is a parameter wrapper,it can package function paramters to a single dynamic object.It looks like TypeList in "Modern C++ design".

You can use it like this:

some place of your code:

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

other place of your code:

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

The second one is a generic callback wrapper,it has some special point compare to other wrappers:
1.This template class has a dynamic base class,which let you use a single type object represent all wrapper objects.
2.It can wrap the callback together with it's parameters,you can excute the callback sometimes later with the parameters.

You can use it like this:

somewhere of your code:

void Test1(int i)
{
}

void Test2(bool b,int i)
{
}

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

otherwhere of your code:

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

Here is a part of the codes:

parameter wrapper:

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;
}

callback wrapper:

#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();
}
soul
  • 3
  • 1

1 Answers1

0

They look useful to me. In the standard library, there is std::tuple and std::function which do similar things.

So, if it's worth having something like this in the standard library, lots of other people probably think being able to write code using patterns enabled by your wrappers is useful.

Scott Langham
  • 58,735
  • 39
  • 131
  • 204
  • If it's in the standard library, then surely you should use the standard library versions instead of reinventing the wheel. – interjay Jun 18 '12 at 15:21
  • Maybe... but that wasn't the question. And implementing these yourself is a great way to learn and develop skills. – Scott Langham Jun 18 '12 at 15:22
  • Thanks for the advice,but i have to say no one carefully check my classes. My class is very diffrent from std::function,because it has a base class which is not a template,so you can restore 100 diffrent callback objects in a pointer array,like vector. Imaging how could you restore 100 diffrent callback objects through std::function,they are totally diffrent type objects. – soul Jun 19 '12 at 12:04