Reputation:
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 ();
}
Upvotes: 0
Views: 2033
Reputation: 3474
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?
Upvotes: 0
Reputation: 47770
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.
Upvotes: 0
Reputation: 40319
I always believe that void* is your friend when you want elegance in these things.
Upvotes: 1