Boost logo

Boost :

From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2006-05-30 07:55:55


Tobias Schwinger wrote:
> João Abecasis wrote:
>
>>1 - support for function pointers was completely broken. Specifically, I
>>learned that result_of doesn't handle cv-qualified function pointers.
>
>
> <snip>
>
>
>>3 - Function references weren't handled at all.
>
>
> Taking the function argument by value (just like the STL) could help.
...which might be why result_of doesn't address the cases you describe.

We can still optimize the forwarding from unpack_args to unpack_args_impl
and the client can optimize the forwarding to unpack_args by explicitly
specifying the first template argument (see attached code).

 
Regards,

Tobias


#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/type_traits/is_class.hpp>
#include <boost/type_traits/add_reference.hpp>

namespace boost { namespace somewhere
{
  namespace utility
  {
    template<typename F> struct forward_functor
      : mpl::eval_if< is_class<F>, add_reference<F>, mpl::identity<F> >
    { };
  }
  namespace detail
  {
    template <typename F> struct func_acceptor_impl
    {
      static void accept_func(F f); // take f by whatever F is
    };
  }

  template <typename F> void accept_func(F f) // take f by value
  {
    detail::func_acceptor_impl<
        typename utility::forward_functor<F>::type >::accept_func(f);
  }

  //----

  template<typename F>
  void performance_critical_algorithm(F f)
  // client that uses the forward_functor metafunction and a non-deduced
  // template argument to reduce copying
  {
    for (; /* often */ ;)
      accept_func< typename utility::forward_functor<F>::type > (f);
  }

  struct a_class { };

  void test() // instantiates templates
  {
    accept_func( static_cast< void(&)() > ( test) );
    accept_func( test );
    accept_func( static_cast< void(*)() > (& test) );
    accept_func( & test );
    accept_func( a_class() );

    performance_critical_algorithm( static_cast< void(&)() > ( test) );
    performance_critical_algorithm( test );
    performance_critical_algorithm( static_cast< void(*)() > (& test) );
    performance_critical_algorithm( & test );
    performance_critical_algorithm( a_class() );
  }

} }


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk