|
Boost : |
From: Peter Dimov (pdimov_at_[hidden])
Date: 2002-02-26 12:06:14
From: "Jaakko Jarvi" <jajarvi_at_[hidden]>
> > If you are allowed to wrap the functions, the solution is to use a
> > polymorphic function object:
> >
> > struct foo
> > {
> > int operator()(int x) const { return 2 * x; }
> > double operator()(double x) const { return 3.0 * x; }
> > };
> >
> > _but_ this 'foo' won't work with the short form of boost::bind because
its
> > return type cannot be deduced automatically (no typeof!).
>
> The lambda library does have a way to define a function object, which
> overloads the operator() and still defines the return types correctly.
> The foo struct needs to define a traits template that maps the
> function argument types to the return type.
> Smaragdakis and McNamara are using this technique in their FC++ library.
>
> With this technique, foo would look like:
>
> struct foo : public has_sig
> {
>
> template<class Arg>
> struct sig {
Yes, it's doable. My 'expression' library used a standalone template:
template<class F, class A1 = missing, class A2 = missing> struct ret
{
typedef ... type;
};
(it was limited to two arguments.)
A scalable solution would be
template<class F, class L> struct ret // L is the argument list
{
typedef ... type;
};
Using a separate class instead of a nested 'sig' is non-intrusive, i.e. it
works with function objects that don't necessarily know about the expression
template library. (The default ret<> still returns F::result_type.)
Either way, I still think that the right approach is to write a "why typeof"
paper instead of coming up with cunning workarounds for the language
shortcomings. (hint) :-)
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk