views:

585

answers:

3

Couldn't creatively shorten the title :)

I have been using a variation of the below solution, however I always wondered if there is a better/cleaner way to implement it. I am looking for non-boost solution. We can, though, look at the implementation of boost and C++0x, as it will soon be relevant.

//Notice the use of template template parameter
template <template <typename> class Callback>   
class A {
   Callback <A> m_func;
   public:
     A (Callback <A>  func):  m_func (func) {}
     void call () { m_func(*this);}

};

template <typename T>
struct MYCallback
{
   void operator () (const T&t) {}

};


void Test()
{
   typedef A<MYCallback> AType;

   MYCallback<AType> callback;
   AType a (callback);
   a.call ();

}

Another, a more suncinct way, is to use tr1::function, which will become defuct-to with new standardization:

#include <tr1/functional>


class A {
   std::tr1::function <void (const A&)>  m_func;
   public:
     template <class Callback>
     A (Callback func) :  m_func (func) {}

     void call () { m_func(*this);}

};

template <class T>
struct My_callback
{
   void operator () (const T&t) {}

};

void Test ()
{
   My_callback <A> c;
   A a (c);
   a.call ();
}
+1  A: 

I always believe that void* is your friend when you want elegance in these things.

Paul Nathan
Please provide example of using a recursion with callbacks in order to avoid dependencies? thanks
A: 

One way you can do it is with a derived class:

template <class Callback>   
class A {
   Callback m_func;
   public:
     A (Callback  func):  m_func (func){}
     void call () { m_func(*this);}

};

template <typename T>
struct MYCallback
{
   void operator () (const T&t) {}

};


struct AConcrete : public A<MYCallback<AConcrete> >
{
  template <class T>
  AConcrete(T t): A<MYCallback<AConcrete> > (t) {}
};

void Test()
{

   MYCallback<AConcrete> callback;
   AConcrete a (callback);
   a.call ();

}

PS: Recursion is tough with C++ templates.

jpalecek
A: 

If you're just looking for clean-up advice, I'd suggest making 'My_callback' a normal class, not a class template. There's not obvious need for it to be a template in this case. Instead, make its apply operator templated or fill in A directly if My_callback only deals with A instances:

#include <tr1/functional>

class A {
   std::tr1::function <void (const A&)>  m_func;
   public:
     template <class Callback>
     A (Callback func) :  m_func (func) {}

     void call () { m_func(*this);}

};

struct My_callback
{
   template <class T>
   void operator () (const T&t) {}
};

int main ()
{
   My_callback c;
   A a (c);
   a.call ();
}

Otherwise, It looks pretty good as is. Could you be more specific in how you hope to clean it up or simplify it?

Aaron