Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2008-04-29 05:43:43


The difficulty of implementing the result_of protocol has always
bothered me. I've often found myself writing a primary result<...>
template and several specializations to handle different
cv-qualifications, and I've still not felt that I was doing it quite
right. It's lucky that operator() has to be a member function, or I'd
be worried about capturing the r/lvalue-ness of the function object
itself.

Now I just ran into another issue, from the other side of the result_of
interface. If I have a function template taking a function object
argument by reference, and I want to use result_of with it, I need to do
something special to account for the case where I've been passed a
function reference. To wit:

         template <class F>
         typename result_of<F()>::type
         call(F const& f)
         {
             return f();
         }

         int f() { return 0; }

         int x = call(f);

The problem is that in the above case, F is deduced as int(), and we
form an illegal function type (one that itself returns a function type)
in result_of<F()>::type.

To deal with this I need something more like

         template <class F>
         typename result_of<
             typename mpl::if_<
                   is_class<F>
                 , F
                 , typename add_pointer<F>::type
>::type()
>::type
         call(F const& f)
         {
             return f();
         }

Is there an easier way?

-- 
Dave Abrahams
Boost Consulting
http://boost-consulting.com

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