|
Boost Users : |
Subject: Re: [Boost-users] Delegating to boost::function with arbitrary signature
From: Alexander Lamaison (awl03_at_[hidden])
Date: 2013-12-16 09:10:03
TONGARI J <tongari95_at_[hidden]> writes:
> 2013/12/15 Alexander Lamaison <span dir="ltr"><mailto:awl03_at_[hidden]></span>
> TONGARI J <mailto:tongari95_at_[hidden]> writes:
>
>> > 2013/12/14 Alexander Lamaison <span dir="ltr"><mailto:mailto:awl03_at_[hidden]></span>
>> > I've asked this question on Stack Overflow but not found a solution yet:
>> > http://stackoverflow.com/q/20578575/67013. It's
>> > Boost.Function/MPL-related so I'll ask here too.
>> >
>> > I'm trying to create something like a `boost::function`, but with an
>> > extra 'smart handle' tucked inside, which controls the lifetime of a
>> > resource the functions needs to execute correctly.
>> >
>> > If I didn'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've got but gets a compile error, presumably, because I'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't think I can declare the 'params' 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'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: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
This works well. The key was `operator Signature*()`. Clever idea,
thanks!
I didn't expect it to work because I though `boost::function` would pull
out the `Signature*` via the cooersion operator, and then the
`library_function` would be destroyed before the call was made.
However, this code proves that it has the desired behaviour, so it must
be keeping a copy of the `library_function` instance inside
`boost::function`: http://ideone.com/BZvuk9.
I didn't use`make_library_function` because inferring the signature
from the raw function isn't something I need.
If you would like to add this answer to the Stack Overflow qusetion,
I'll happily give you the brownie points :)
Thanks,
Alex
-- Swish - Easy SFTP for Windows Explorer (http://www.swish-sftp.org)
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