
On Sun, Apr 27, 2008 at 4:22 PM, Steven Watanabe <watanabesj@gmail.com> wrote:
/* Check if a function/functor Fun has a given signature Sig */
template<typename Fun, typename Sig> struct is_compatible { /* Check for a function */ template<class U> static yes_type check(typename enable_if<is_same<U, Sig> >::type*);
/* Check for a functor */ template<class U, Sig U::*> struct helper;
template<class U> static yes_type check(helper<U, &U::operator()>*);
This is not correct. It does not handle
struct f { void operator()() *const* {} };
Further, it cannot handle implicit conversions of the argument types and return types.
I have thought again on this issue and it come up to the conclusion that this is really a feature :-) In the context of multisignature boost.function the implicit conversion of the argument could lead to misbehaviour. As example define the following signatures: typedef boost::mpl::vector < int(double) , int(int) > Signatures; And define the multi-signature function on them boost::multi_signature_function::function<Signatures> f; Now you have two functions int foo1(double); int foo2(int); Without implicit conversion of type arguments the following works as expected: f = &foo1; f = &foo2; But if implicit conversion is in then, because int(double) is declared BEFORE int(int) then the first will shadow the second in the overload hierarchy and what we end up is that f = &foo2; overwrites the previous assignment so that the internal boost::function corresponding to int(double) is assigned to &foo2, while the other boost::function corresponding to int(int) is still empty. So the bottom line is that implicit conversion of the argument types is not good in our context. What the user should do is to wrap the function in a boost function BEFORE to assign to multi-signature. As example int foo(int); boost::multi_signature_function::function<int(double)> f; boost::function<int(double)> wrapper; wrapper = &foo; // now it works because there is no ambiguity for a standard boost::function... f = wrapper; // ... and it's assigned to the multi-signature f also if foo has different signature. Thanks Marco P.S: So now the only remaining issue (the other was promoted to a feature!) is the handling of pointers to const member functions. BTW note that the wrapping trick would work also to handle this case, but in this case a 'native' solution would be preferable.