function (object) return and argument metafunctions?

Hi, I know we've discussed this in the past, but did we ever settle on an interface for deducing the return and parameter types of function (object)s? Doug G.'s result_of<F(a,b)> template works for return types, but it's not very portable and is not even in Boost proper AFAIK. Many function objects and all function pointers have specific (non-templated) parameter types, and it would be extremely valuable to be able to deduce those as well. It's hard to believe that with all the functional programming libraries we have, there's no standardized facility for this sort of deduction. -- Dave Abrahams Boost Consulting www.boost-consulting.com

On Fri, 30 Jan 2004, David Abrahams wrote:
I know we've discussed this in the past, but did we ever settle on an interface for deducing the return and parameter types of function (object)s? Doug G.'s result_of<F(a,b)> template works for return types, but it's not very portable and is not even in Boost proper AFAIK.
I've been meaning to propose it for Boost (fast track? hmmmm), but we'll have to have some wrapper for braindead compilers without any partial specialization.
Many function objects and all function pointers have specific (non-templated) parameter types, and it would be extremely valuable to be able to deduce those as well.
Well, we could extend function_traits a bit... Doug

Douglas Paul Gregor <gregod@cs.rpi.edu> writes:
On Fri, 30 Jan 2004, David Abrahams wrote:
I know we've discussed this in the past, but did we ever settle on an interface for deducing the return and parameter types of function (object)s? Doug G.'s result_of<F(a,b)> template works for return types, but it's not very portable and is not even in Boost proper AFAIK.
I've been meaning to propose it for Boost (fast track? hmmmm), but we'll have to have some wrapper for braindead compilers without any partial specialization.
Many function objects and all function pointers have specific (non-templated) parameter types, and it would be extremely valuable to be able to deduce those as well.
Well, we could extend function_traits a bit...
Not another multi-valued traits blob, please! I want metafunctions. The best answer might be a single metafunction returning an MPL sequence of argument types. -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
Douglas Paul Gregor <gregod@cs.rpi.edu> writes:
Well, we could extend function_traits a bit...
Not another multi-valued traits blob, please! I want metafunctions. The best answer might be a single metafunction returning an MPL sequence of argument types.
I've asked you before: a function type is a perfectly good sequence, why not just extend MPL to iterate over it? (Which I recall MPL "v2" already did at one point, to enable list(int, float, void*) to work.)

"Peter Dimov" <pdimov@mmltd.net> writes:
David Abrahams wrote:
Douglas Paul Gregor <gregod@cs.rpi.edu> writes:
Well, we could extend function_traits a bit...
Not another multi-valued traits blob, please! I want metafunctions. The best answer might be a single metafunction returning an MPL sequence of argument types.
I've asked you before: a function type is a perfectly good sequence, why not just extend MPL to iterate over it? (Which I recall MPL "v2" already did at one point, to enable list(int, float, void*) to work.)
Two reasons: 1. It's not very portable, so we can't "just" extend MPL to iterate over the function type 2. It doesn't cover function objects with fixed argument lists, so we can't "just" extend MPL to iterate over a function type -- Dave Abrahams Boost Consulting www.boost-consulting.com

David Abrahams wrote:
Hi,
I know we've discussed this in the past, but did we ever settle on an interface for deducing the return and parameter types of function (object)s? Doug G.'s result_of<F(a,b)> template works for return types, but it's not very portable and is not even in Boost proper AFAIK. Many function objects and all function pointers have specific (non-templated) parameter types, and it would be extremely valuable to be able to deduce those as well.
It's hard to believe that with all the functional programming libraries we have, there's no standardized facility for this sort of deduction.
I'm joining this thread slightly late but nonetheless, this is on my wish-list too and I've got code right now that would greatly benefit from standardized return type deduction. What I want to add to the discussion is that I believe we need _two_ versions of return_type (or whatever we choose to call it). Even though I like the power and syntax of the result_of<F(a,b)>, I'd say it's not unreasonable to be in a situation where the argument types (if any) simply aren't know. In such cases a plain return_type<F> that would atleast make an "educated guess" would be better than nothing. Just my 2c // Fredrik Blomqvist

On Sun, Feb 08, 2004 at 09:04:11PM +0100, Fredrik Blomqvist wrote:
What I want to add to the discussion is that I believe we need _two_ versions of return_type (or whatever we choose to call it). Even though I like the power and syntax of the result_of<F(a,b)>, I'd say it's not unreasonable to be in a situation where the argument types (if any) simply aren't know. In such cases a plain return_type<F> that would atleast make an "educated guess" would be better than nothing.
Here you go: template <class F> struct educated_guess_return_type { typedef int result_type; }; It is right every time the actual return type is "int"! :) Seriously, can you show a case how "educated guess" is better than nothing? My instincts tell me that it's better to fail to compile than to guess the wrong type and start having random implicit conversions start kicking in. In the (rare?) case where the return type of F doesn't depend on its arguments, then it either (a) it should probably just declare an F::result_type (in which case I think result_of<F> may work), or (b) just doing result_of<F(int,int)> (where 'int' is arbitrary) seems likely to 'get the right answer' anyway. -- -Brian McNamara (lorgon@cc.gatech.edu)

On Sunday 08 February 2004 03:27 pm, Brian McNamara wrote:
Seriously, can you show a case how "educated guess" is better than nothing? My instincts tell me that it's better to fail to compile than to guess the wrong type and start having random implicit conversions start kicking in.
As with result_of, if you have to guess, guess void. When you're right, it works; when you're wrong, it fails to compile.
In the (rare?) case where the return type of F doesn't depend on its arguments, then it either (a) it should probably just declare an F::result_type (in which case I think result_of<F> may work),
If F::result_type exists, result_of will use it. For compilers that can't handle SFINAE, I think we'll always have to go with F::result_type. Doug

Brian McNamara wrote:
On Sun, Feb 08, 2004 at 09:04:11PM +0100, Fredrik Blomqvist wrote:
What I want to add to the discussion is that I believe we need _two_ versions of return_type (or whatever we choose to call it). Even though I like the power and syntax of the result_of<F(a,b)>, I'd say it's not unreasonable to be in a situation where the argument types (if any) simply aren't know. In such cases a plain return_type<F> that would atleast make an "educated guess" would be better than nothing.
Here you go:
template <class F> struct educated_guess_return_type { typedef int result_type; };
It is right every time the actual return type is "int"! :)
Seriously, can you show a case how "educated guess" is better than nothing? My instincts tell me that it's better to fail to compile than to guess the wrong type and start having random implicit conversions start kicking in.
Re-reading my previous post I can see I was unclear. I'm Not advocating a solution that would never fail! What I carelessly referred to by "educated guess" was to use the "old" pre result_of techniques in the non argument-type version. Basically piecing together function_traits<>, member_function_traits<> and lastly a fallback to ::result_type. That technique doesn't require argument types but would still cover many common cases. result_of may simply succeed with deduction when this technique fails.
In the (rare?) case where the return type of F doesn't depend on its arguments, then it either (a) it should probably just declare an F::result_type (in which case I think result_of<F> may work), or The result_of implementation in the sandbox doesn't seem to do that (it always requires the call syntax). But if it is possible that would be great of course.
Regards // Fredrik Blomqvist
participants (6)
-
Brian McNamara
-
David Abrahams
-
Douglas Gregor
-
Douglas Paul Gregor
-
Fredrik Blomqvist
-
Peter Dimov