
Hi Steven, Thanks for your response, I think it's going to save me a lot of messing around! On 21 Aug 2009, at 15:29, Steven Watanabe wrote:
AMDG
Edward Grace wrote:
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.
The type of a function pointer is unsigned(*)(). The return type is easily deducible from the type of the function pointer. For function objects, you need to use result_type or result, since it is impossible to deduce the result type automatically
Ok, that's kind of what I suspected -- but I didn't know why.
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; } };
In the current standard it is impossible to deduce the result without using the result_type typedef.
At least this means I won't waste my time trying to figure out what I'm doing wrong! It seems quite unedifying having to make sure the user adds some, apparently arbitrary, magic typedef to their functors in order to make sure it works. My original motivation was to form a helpful compile time assert for the user, which I thought would be good practise. It appears all this does is to shift a conceptually straightforward problem (make sure your functor/function returns something) to an even more obscure one "ordinary functions are fine but make sure you define a return_type typedef in your functions oh.. and make sure the return type of the operator()() is the same as that... " Then I have to add a way of sanely catching if they have not done this - I doubt I can... Crazy! Do you know if, boost::bind and or boost::function etc automatically add this typedef? If so some of the pain (and errors) would be alleviated by the automatic typedef. I they don't, perhaps they should. To make matters worse (rhetorical); if I have a class with a set of different functors each with a different return type how can I make sure the magic typedef (result_type) is simultaneously correct for each? Yuck! So, my best solution -- I think -- is to make sure my functions/ functors are unary and of the form: void function_body(double return&); that should be fairly easy to check for in all cases. To users it will appears weird in the extreme of course..... ...but it's C++, they should be used to it by now (ducks and exits stage left).
In C++0x, result_of is specified using decltype, so it won't be necessary.
Rapidly I'm coming to the conclusion that I'm not going to bother writing templated code until C++0x is finished -- there's (still) too much missing. Boost does a good job of papering over many of the cracks, but they are still there under the surface! Cheers, -ed