
On Thu, May 1, 2008 at 3:13 PM, Peter Dimov <pdimov@pdimov.com> wrote:
David Abrahams:
on Tue Apr 29 2008, "Daniel Walker" <daniel.j.walker-AT-gmail.com> wrote: ...
template <class F> typename result_of<F const&()>::type call(F const& f) { return f(); }
Fine, then take the case where call takes f by value; then F can be a function type and result_of<F()> is illegal.
If you call
template <class F> typename result_of<F()>::type call( F f ) { return f(); }
with a function, F will be deduced as a function pointer.
Yes, and I think this is where the problem arises. In this scenario, call(f) looks like a call-by-value, but f is second-class and cannot be treated as a value. The compiler "helps" out by deducing a call by reference, actually a pointer (this comes from C, right?). So, call() requires some metaprogramming type analyses to determine whether it was passed a reference to a builtin, a reference to first-class functor, or a first-class functor value. The compiler determines which of these three occurred using function argument deduction, but result_of doesn't have access to that... well it kind of does with decltype. Regardless, call() still doesn't know what it was passed, and this could cause more trouble down the road. It seems to me it would help matters to add some constraints to the type of call()'s argument such as CopyConstructable, EqualityComparable; i.e. make it a first-class function. Daniel