
On Mon, May 12, 2008 at 7:39 PM, Giovanni Piero Deretta <gpderetta@gmail.com> wrote:
I.e. MSF is the natural extension of boost::function in the realm of polymorphic function objects (well, you still have to choose beforehand the types you want to work with, but it is still much better than boost::function).
[ BTW, by a quick at the code of MSF you do not seem to implement the result_of protocol. You definitely should, as MSF is definitely a polymorphic function object,]
IOW you mean that given typedef boost::msf_function<double(double), int(int),std::string(std::string)> MSF; The implementation should lead to... boost::result_of<MSF(double)>::type i; // i is a double boost::result_of<MSF(int)>::type i; // i is an int boost::result_of<MSF(std::string)>::type i; // i is a std::string Is this correct?
Still your current implementation has a problem.
--strip----
msf_function<int(int), double(double), my_big_int(my_big_int)> x = frob(10);
it has two downsides ... 1) it does N dynamic allocations, one for each signature.
well, a boost::function is allocated (empty) on the stack because it's a member data.
2) it has N copies of 'frob::state', which for a small object as an int it is not a problem, but in principle it can be wasteful
... and a serious problem: As there are n different states, the increment is separate for each type, and not for all of them:
This is more a "behaviour" then a problem, as example I can have a state named calls_counter that counts how many time an operator() has been called for each different type of arguments. In this case having separate state is a need: T operator()(T i) { calls_counter++; ...do something.... return some_value; } The real problem IMHO is that this behaviour is not well documented, I'll fix this.
In practice MSF acts as N different boost::function objects with a think type based dispatcher. I can of course fix the problem by adding another layer of indirection:
Have you tried to fix it with msf_function<int(int), double(double), my_big_int(my_big_int)> x; x = boost::ref( frob(10) ); Indeed boost::function supports ref() and cref() to avoid the copy when is not needed or when the copy is simply wrong. MSF supports ref() and cref() too and forwards them, still wrapped, to the underlying boost::function objects so that no copy of the wrapped polymorphic function object is made. Thanks Marco