$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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() ); 
  }
} }