Boost logo

Boost Users :

Subject: Re: [Boost-users] Delegating to boost::function with arbitrary signature
From: Alexander Lamaison (awl03_at_[hidden])
Date: 2013-12-14 11:24:33


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?

 template<typename Signature>
 class library_function : private boost::function<Signature>
 {
 public:
     library_function(
         shared_ptr<HMODULE> library, Signature* library_funtion)
         :
     m_library(library),
     m_function(library_function)
     {}

     using boost::function<Signature>::operator();

 private:
     shared_ptr<HMODULE> m_library;
     boost::function<Signature> m_function;
 };

error C2243: 'type cast' : conversion from 'library_function<Signature>
 *' to 'const boost::function_base *' exists, but is inaccessible

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