2013/12/15 Alexander Lamaison <awl03@doc.ic.ac.uk>
TONGARI J <tongari95@gmail.com> writes:

> > 2013/12/14 Alexander Lamaison <span dir="ltr"><mailto:awl03@doc.ic.ac.uk></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:

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