Boost logo

Boost :

From: Anthony Williams (anthony.williamsNOSPAM_at_[hidden])
Date: 2002-11-22 08:30:51


David Abrahams writes:
> Anthony Williams <anthony.williamsNOSPAM_at_[hidden]> writes:
>
> > David Abrahams writes:
> > >
> > > Do we have any precedent for ways to find out what the arity and
> > > argument types of an arbitrary function object is (I'm not talking
> > > about function pointers, here, but "functors")?
> >
> > Given that a functor might support more than one argument set, the only way I
> > can think of is to say "do you support this argument set?" rather than "what
> > argument set do you accept?"; in which case you can use the mechanism
> > implemented in boost.lambda, and in my function composition library, to deduce
> > the return type --- have a member template that takes a typelist representing the
> > arguments you wish to pass, and returns the corresponding return type where
> > that argument set is valid, or something else (such as invalid_argument_set)
> > where it isn't (assuming you want to do something else in the case where it
> > isn't, rather than just abort compilation)
> >
> > Does this give you what you want?
>
> No, the inputs are fully-polymorphic Python objects. If I knew what
> "arguments I wish to pass", I'd be all set. I'm only interested in the
> cases where that's deducible from the function object. For the other
> cases, the user can pass me a type sequence directly.

OK, so you have a set of "any" objects, and a functor, and you want to know
what types to extract from your "any" objects to pass as arguments to the
functor?

Well, given that you can only work with a functor of defined arity and
argument types for that information to be available at all, you could just use
the type of Functor::operator() to determine the required information:

struct get_member_func_info;

template<typename Functor,typename Res,typename Arg1>
struct get_member_func_info<Res (Functor::*)(Arg1)>
{
    enum {arity=1};
    typedef Arg1 arg1_type;
};

template<typename Functor,typename Res,typename Arg1,typename Arg2>
struct get_member_func_info<Res (Functor::*)(Arg1,Arg2)>
{
    enum {arity=2};
    typedef Arg1 arg1_type;
    typedef Arg2 arg2_type;
};

not forgetting to handle const/volatile/const volatile member functions too,
then just use

get_member_func_info<&MyFunctor::operator()>::arity, ::arg1_type, ::arg2_type,
etc.

Of course, it won't work if operator() is overloaded, but if there's a defined
arity and argument type set, then you should only be talking about
cv-qualification, and it strikes me as bad design to have a member function
overloaded exclusively on cv-qualification --- this implies that the constness
of the object affects its behaviour.

Anthony

-- 
Anthony Williams
Senior Software Engineer, Beran Instruments Ltd.
Remove NOSPAM when replying, for timely response.

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk