Topic: Issues with result_of -- and yet still, I have a concern


Author: graham-spam@ript.net ("Graham Batty")
Date: Wed, 14 May 2003 17:22:20 +0000 (UTC)
Raw View
Wow, thanks to both of you. That's a great technique. I would have thought
it impossible, since attempting to switch on the typename that way would
cause an error. Guess not, works great with both VC7.1 and GCC3.2.

I still have one concern though, about result_of. It's use of the return
value of the function being passed in seems rather obscure. Especially since
part of the point of result_of is supposed to be to get the return type of
normal function pointers. A simpler form of result_of has to be built to
make result_of work.

It also seems to me that this could cause problems when specializing. For
instance, it would be convenient to be able to have a forwarding template to
specialize result_of like so:
template <typename tList>
struct result_of<my_function_type, tList>
{
    typedef typename my_function_type::something_weird<tList> type;
};

But the way it is now, it would have to be specialized for various argument
counts like so:
template <>
struct result_of<my_function_type ()>
{...};
template <typename tArg1>
struct result_of<my_function_type (tArg1)>
{...};
etc.

It seems to me the only way to mitigate that is by using some custom
extract_return template like so:
template <typename tList>
struct result_of
{
    typedef typename result_of_impl<typename extract_return<tList>::type,
tList>::type type;
};
Or with a call into the default result_of template, giving it tList():
struct result_of
{
    typedef typename result_of_impl<typename result_of<tList ()>::type,
tList>::type type;
};

But WHY? All this hassle is introduced because for some reason, it was
decided to put two discrete types into one template parameter, and one of
them into a notoriously difficult to get at part of the function pointer
type. Is there some benefit to this encoding that I'm not aware of (which is
certainly possible, given that I wasn't aware of the technique brought to my
attention here above)? If not, wouldn't it be better to seperate them out
into their own arguments? This was also a source of a lot of confusion when
I first read that proposal, and I am curious if I am alone in that.

Thanks,
Graham.

""Giovanni Bajo"" <noway@sorry.com> wrote in message
news:%52wa.114968$iy5.3501981@twister2.libero.it...
> "Graham Batty" wrote:
>
> > Here's where things get crazy. How, exactly, is a library supposed to
> > determine the presense or absense of result_type in the class F?
>
> Using SFINAE:
>
> template <typename F>
> struct has_result_type
> {
>     typedef char Yes;
>     typedef double No;
>
>     template <typename T> static Yes test(typename T::result_type* );
>     template <typename T> static No test(...);
>
>     enum { value = (sizeof(test<F>(0)) == sizeof(Yes)) };
> };
>
> --
> Giovanni Bajo
>
> ---
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]
>

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]