Boost logo

Boost Users :

Subject: Re: [Boost-users] Delegating to boost::function with arbitrary signature
From: Michael Powell (mwpowellhtx_at_[hidden])
Date: 2013-12-14 12:12:03


On Sat, Dec 14, 2013 at 10:53 AM, TONGARI J <tongari95_at_[hidden]> wrote:
> 2013/12/15 Alexander Lamaison <awl03_at_[hidden]>
>>
>> TONGARI J <tongari95_at_[hidden]> writes:
>>
>> > > 2013/12/14 Alexander Lamaison <span
>> > > dir="ltr"><mailto:awl03_at_[hidden]></span>
>> > > I&#39;ve asked this question on Stack Overflow but not found a
>> > > solution yet:
>> > > http://stackoverflow.com/q/20578575/67013. It&#39;s
>> > > Boost.Function/MPL-related so I&#39;ll ask here too.
>> > >
>> > > I&#39;m trying to create something like a `boost::function`, but with
>> > > an
>> > > extra &#39;smart handle&#39; tucked inside, which controls the
>> > > lifetime of a
>> > > resource the functions needs to execute correctly.
>> > >
>> > > If I didn&#39;t need the function signature to be completely generic,
>> > > this
>> > > would be easy. I would just create a functor with the correct
>> > > signature, and keep a `boost::function` and the handle as members.
>> > >
>> > > However, I do need generic signatures. The code below is as close as
>> > > I&#39;ve got but gets a compile error, presumably, because I&#39;m not
>> > > able to
>> > > unpack a list of arguments like this:
>> > >
>> > > template<typename Signature>
>> > > class library_function
>> > > {
>> > > public:
>> > > library_function(
>> > > library_handle handle,
>> > > boost::function<result_type(arg1_type, arg2_type)> function)
>> > > :
>> > > m_handle(handle),
>> > > m_function(function)
>> > > {}
>> > >
>> > > typename result_type operator()(arg1_type arg1, arg2_type arg2)
>> > > {
>> > > return m_function(arg1, arg2);
>> > > }
>> > >
>> > > // I don&#39;t think I can declare the &#39;params&#39; like this
>> > > ...
>> > > typename boost::function_types::result_type<Signature>::type
>> > > operator()(
>> > > boost::function_types::parameter_types<Signature> params)
>> > > {
>> > > return m_function(params); // ... nor unpack them like this
>> > > }
>> > >
>> > > private:
>> > > boost::function<Signature> m_function;
>> > > library_handle m_library;
>> > > };
>> > >
>> > > I think `params` is an MPL list, so what I&#39;ve actually done is
>> > > declare a
>> > > call operator with a single MPL-list parameter. My MPL-foo is not
>> > > good.
>> > > Is there a way to convert the list to a legal definition of multiple
>> > > function paramters?
>>
>> > Why not just derive from boost::function so you get the call operator
>> > for free?
>>
>> I avoided publicly-inheriting from `boost::function` because that's just
>> asking for slicing problems. Private inheritance seemed like a good
>> idea but I then run into a problem passing the resulting object to
>> anything expecting a `boost::function`. Instead of treating as any
>> regular callable object, the compiler knows that it inherits from a
>> `boost::function` and complains that the conversion is hidden. Maybe
>> there's some way round this?
>
>
> Another thought is to use boost::function directly, and provide a make
> function:

There you go. Simple decorator pattern. Nice and transparent and tucked away.

> template<typename Signature>
> boost::function<Signature> make_library_function(shared_ptr<HMODULE>
> library, Signature* f)
> {
> return library_function<Signature>(library, f);
> }
>
> And library_function becomes:
>
>> template<typename Signature>
>> class library_function
>> {
>> public:
>> library_function(
>> shared_ptr<HMODULE> library, Signature* library_funtion)
>> :
>> m_library(library),
>> m_function(library_function)
>> {}
>>
>> operator Signature*() const { return m_function; }
>>
>>
>> private:
>> shared_ptr<HMODULE> m_library;
>> Signature* m_function;
>> };
>
>
> Note: code not tested
>
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net