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:

   "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,

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).



#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
     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.
   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, gregod at, cpdaniel at, john at