Boost logo

Boost :

Subject: [boost] Checking for return types (result_of) - redux..
From: Edward Grace (ej.grace_at_[hidden])
Date: 2009-08-21 09:58:41


Dear all,

So, I have nearly figured out what to do, however it seems --
deliberately in fact, that the behaviour of result_of<???> is
different when passed a function and a functor. Though I am not
sure, the documentation:

   http://www.boost.org/doc/libs/1_39_0/libs/utility/
utility.htm#result_of

   "When F is a class type with a **member type result_type**,
result_of<F(T1, T2, ..., TN)> is F::result_type."

appears to imply that this is the way it should be (emphasis mine).
So does the following in fact,

   http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1454.html

So it seems that my original instinct (it's hard) was correct after all.

Surely result_of<functor()>::type should resolve to the result type
in the same way as it does for anything else callable (like a
function). Anything else seems to be a big fat pain in the rear...

Or, put another way, can I get what I want? Example below, the
problem is s.member_function(one).

Help!

-ed

#include <boost/mpl/assert.hpp>
#include <boost/utility/result_of.hpp>
#include <boost/type_traits/is_same.hpp>

void void_f() {}
unsigned unsigned_f() { return 1; }

// We want member_function to accept any callable object (functor,
// function pointer) thing that returns an unsigned integer.
//
// value = f();
//
// Should work.
struct S {
   template <class O>
   void member_function(O f) {
     // We require that the function/functor f returns an unsigned
integer.
     BOOST_MPL_ASSERT( (boost::is_same<unsigned, typename
boost::result_of<O()>::type>) );
     unsigned sum(0);
     sum += f();
   }
};

struct one_functor {
   // This is apparently needed if we want to use result_of<..> on
nullary functors like this.
   // typedef unsigned result_type;
   unsigned operator()() { return 1; }
};

int main() {
   S s;
   one_functor one;
   unsigned val=one(); // We can assign to the val from the
                      // instantiated functor.
   // THIS DOES NOT WORK AS IT SHOULD...
   s.member_function(one); // This does not work as
                           // boost::result_of<O()> is, apparently
                           // one_functor instead of unsigned
                            //
                            // Uncommenting the typedef in
one_functor makes it
                            // work - but it seems like a right pain
in the rear.

   s.member_function(unsigned_f); // Works fine.
   // s.member_function(void_f); // Dies as it should!
   return 0;
}


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