myelin: C++ delegates without a helper script

Marcel Mueller wrote to say that you can do it all just fine without the helper script, if you make a template for every possible number of function arguments.

This was one approach I considered before writing the helper script, but rejected because the idea of having a whole heap of classes with ARG1, ARG2, ARG3, etc just felt wrong. As Marcel states, however, doing it this way means you can do it all with the C++ compiler (no dependency on Perl, etc) and the resulting delegates can be used as STL functors -- useful advantages :-)

Here is his message:

Hi,

if you write a one generic delegate class for each number of function
arguments you do not longer need a perl helper to implement the call
method.

To hide this implementation to the user it is recomended to create the
delegates with an overloaded factory function like the STL
mem_fun... functions do.

Something like this:

// delegate workers
template
class GenericDelegate0 // no args
private:
T* _that;
R (T::*_func)();
public:
GenericDelegate0( T* that, R (T::*func)() )
         : _that(that)
         , _func(func)
        {}
        R operator()() { return (_that->*_func)(); }
};

template
class GenericDelegate1 // 1 arg
private:
T* _that;
R (T::*_func)(ARG1);
public:
GenericDelegate1( T* that, R (T::*func)(ARG1) )
         : _that(that)
         , _func(func)
        {}
        R operator()(ARG1 arg1) { return (_that->*_func)(arg1); }
};

...

// delegate factory
template
GenericDelegate0 GenericDelegate( T* that, R (T::*func)() )
{  return GenericDelegate0(that, func);
}
template
GenericDelegate0 GenericDelegate( T* that, R (T::*func)(ARG1) )
{  return GenericDelegate1(that, func);
}
...


The returned delegates additionally meets the requirements of STL
function objects (functors).

If you want to use them as explicitly type checked parameters (rather
than templates), you have to use the worker classes directly:
e.g.:

typedef GenericDelegate1 mySpecialDelegate;