|
Boost : |
Subject: Re: [boost] boost::bind result type
From: Daniel Walker (daniel.j.walker_at_[hidden])
Date: 2010-07-20 11:06:38
On Tue, Jul 20, 2010 at 10:45 AM, David Sankel <camior_at_[hidden]> wrote:
> 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!
But this is not a generic solution. It is a very specific solution
that relies on internal types and implementation details of
boost::bind. It may not work for all releases of boost::bind and may
not work with other bind implementations.
Daniel Walker
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk