I came across the following blog post which explains how to build C++ delegates using variadic templates: http://blog.coldflake.com/posts/2014-01-12-C++-delegates-on-steroids.html
I'm reproducing the Delegate class in the post here:
template<typename return_type, typename... params>
class Delegate
{
typedef return_type (*Type)(void* callee, params...);
public:
Delegate(void* callee, Type function)
: fpCallee(callee)
, fpCallbackFunction(function) {}
template <class T, return_type (T::*TMethod)(params...)>
static Delegate from_function(T* callee)
{
Delegate d(callee, &methodCaller<T, TMethod>);
return d;
}
return_type operator()(params... xs) const
{
return (*fpCallbackFunction)(fpCallee, xs...);
}
private:
void* fpCallee;
Type fpCallbackFunction;
template <class T, return_type (T::*TMethod)(params...)>
static return_type methodCaller(void* callee, params... xs)
{
T* p = static_cast<T*>(callee);
return (p->*TMethod)(xs...);
}
};
And an example of how to use the class is given here:
class A
{
public:
int foo(int x)
{
return x*x;
}
int bar(int x, int y, char a)
{
return x*y;
}
};
int main()
{
A a;
auto d = Delegate<int, int>::from_function<A, &A::foo>(&a);
auto d2 = Delegate<int, int, int, char>::from_function<A, &A::bar>(&a);
printf("delegate with return value: d(42)=%d\n", d(42));
printf("for d2: d2(42, 2, 'a')=%d\n", d2(42, 2, 'a'));
return 0;
}
The technique is pretty cool, except that I would also like to have the Delegate class manage the callee's lifetime (in other words I would like to instantiate A on the heap and when the Delegate instance is deleted or goes out of scope, it should also be able to delete the callee (the A instance in this case)). Is there a simple way of doing this? Am I missing something? One solution would be to also pass a deleter object, which would cast the void* fpCallee to the correct type and then call delete ont it. Is there a better solution for this?