
On Wed, Apr 30, 2008 at 12:04 AM, shunsuke <pstade.mb@gmail.com> wrote:
David Abrahams wrote:
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?
How about `boost::decay`? Or an "imaginary" function `apply` might be better.
template<class F> typename result_of<typeof_apply(F const &)>::type call(F const &f) { return apply(f); }
Aha! That just made me realize that I didn't fully understand what Dave was getting at yesterday. call() uses call-by-reference, and since boost::result_of<> treats all references as function references, you have to somehow decompose the reference before hand to determine what to pass to result_of<> so that it will do the right thing. OK. Then the snippet I sent yesterday will work for function references but not references to function objects. Still, I think the best thing to do in this case is to make call() accept only first-class function objects by value... especially since all the tools needed to treat built-in functions or references to function objects as values will be available in C++0x as soon as you #include <functional>. For example: template <class F> typename std::result_of<const F()>::type call(const F f) { return f(); } int f() { return 0; } struct g { typedef int result_type; int operator()() const { return 0; }; }; // Promote built-in function to first-class int x = call(std::function<int()>(f)); // Call-by-reference int y = call(std::cref(g())); // Call-by-value int z = call(g()); Actually, you don't need to use function<> with the call() above since the function reference will be deduced correctly, but if call() used a concept to require AdaptableGenerator or the like, then you would have wrap the built-in in an actual functor. I believe that on modern optimizing compilers this would be as efficient as implementing call() using call-by-reference, and it's much simpler than using meta programming to analyze the reference argument. Is there a reason not to use this idiom? ... other than using references for some sort of sub-class polymorphic functors, which isn't even remotely cool. Daniel Walker