|
Boost : |
Subject: Re: [boost] boost::bind result type
From: David Sankel (camior_at_[hidden])
Date: 2010-07-20 10:45:52
On Mon, Jul 19, 2010 at 6:42 PM, Daniel Walker <daniel.j.walker_at_[hidden]>wrote:
> On Mon, Jul 19, 2010 at 5:37 PM, David Sankel <camior_at_[hidden]> wrote:
> > I'm wondering if there's a way I can generically get the result type of
> > boost bind.
> >
> > I'd like to write something along these lines:
> >
> > template< typename StreamT, typename Sink >
> > typename boost::result_of< boost::Bind( StreamT, boost::arg<1>, Sink )
> >>::type
> > apSink( StreamT t, Sink sk )
> > {
> > return boost::bind( t
> > , _1
> > , sk
> > );
> > }
> >
> > I'm not interested in a boost::function solution because I require that
> uses
> > apSink's result can be inlined. Any ideas? Perhaps one of these other
> > bind-like libraries has an answer to this.
>
> To my knowledge there is no general way to declare the return type of
> boost::bind (or a Boost Lambda expression). In C++03 the best we can
> do is boost::function, which can store arbitrary function objects
> without having to know the type.
Thanks Daniel. I have found a way do, somewhat awkwardly, what I want in
C++03 so I'll give my solution below.
Look at the header bind.hpp in the section commented "generic function
objects", the return types are shown to be of the form:
_bi::bind_t< R
, F
, typename _bi::list_av_1<A1>::type
>
Where R is either the Z in a bind<Z> form or _bi::unspecified for the more
common form. The list of arguments are part of the third template parameter.
So my function then becomes:
template< typename StreamT, typename Sink >
boost::_bi::bind_t< boost::_bi::unspecified
, StreamT
, typename boost::_bi::list_av_2< Sink
, boost::arg<1>
>::type
>
apSink( StreamT t, Sink sk )
{
return boost::bind( t
, sk
, _1
);
}
However, this is really bad form as is anytime when passing an instance of
bind_t to an outside function. The reason is that bind_t doesn't have normal
callable semantics if it is used within another call to bind. To fix this
problem boost::protect must be used. The following is the final version of
my function:
template< typename StreamT, typename Sink >
boost::_bi::protected_bind_t<
boost::_bi::bind_t< boost::_bi::unspecified
, StreamT
, typename boost::_bi::list_av_2< Sink
, boost::arg<1>
>::type
>
>
apSink( StreamT t, Sink sk )
{
return boost::protect( boost::bind( t
, sk
, _1
)
);
}
Works great!
David
-- David Sankel Sankel Software www.sankelsoftware.com 585 617 4748 (Office)
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk