Boost logo

Boost :

From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2007-05-21 05:37:00


Eric Niebler wrote:
> I've noticed something odd about the specification of tr1::result_of. In
> result_of<F()>::type, if F is a class type that doesn't have a nested
> result_type typedef, the result is "void". This is only true for F();
> that is, when there are no arguments. That leads to the following
> strangeness:
>
> struct foo {
> typedef int result_type;
> };
>
> struct bar {
> template<class Sig> struct result {
> typedef int type;
> };
> };
>
> result_of<foo()>::type == int // 1
> result_of<bar()>::type == void // 2 huh?
>
> result_of<foo(int)>::type == int // 3
> result_of<bar(int)>::type == int // 4
>
> This is the way it's specified in TR1, and boost::result_of implements
> this behavior faithfully, but I just can't understand why (2) is void
> instead of int. Can somebody explain it to me?

Ha! I've been wondering the same and figured the following reasons (but
they aren't really good ones, IMO):

There is no full specialization for member templates, so it's
(seemingly) impossible to create a nested result<> metafunction (that's
not really a problem since an unused extra template argument with a
default allows us to define a partial specialization instead).

If there was full specialization for member templates it wouldn't be
lazy (IOW share its PoI with the surrounding class, just like
operator()) which could be impractical in cases where the presence of a
such a call operator depends on the type (== the template arguments) of
the surrounding class (but 1. it's impractical anyway because operator()
must be a class member and 2. there is no need to define a full
specialization in the first place).

I'd be interested to know better reasons, too.

Regards,
Tobias


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk