Boost logo

Boost :

From: Daniel Walker (daniel.j.walker_at_[hidden])
Date: 2007-05-21 14:57:44


On 5/21/07, Eric Niebler <eric_at_[hidden]> wrote:
>
> Peter Dimov wrote:
> > 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.
> >
> > This special case is needed in situations such as:
> >
> > template<class F> struct X
> > {
> > F f_;
> >
> > result_of<F()>::type operator()() { return f_; }
> >
> > template<class A1>
> > result_of<F(A1)>::type operator()(A1& a1) { return f_(a1); }
> >
> > // ...
> > };
> >
> > where X can be instantiated with non-nullary function objects, or with types
> > that aren't function objects at all, as in:
> >
> > X<int> x;
> >
> > The above instantiates the declaration of X::operator()(), which attempts to
> > instantiate result_of<int()>, which would fail without the kludge.
>
> Well, my reading of the spec makes the program ill-formed. F needs to be
> a class type for this odd rule to kick in.
>
> But ... yech. And the different behavior between foo and bar in my
> example is that we know how to test for member typedefs but not for
> member templates.

I agree with your reading. I think the above is ill-formed according
to section 3.4/3.

Incidentally, we do know how to test for member templates now. Here's
a thread archive discussing my patch to MPL that does this:
http://tinyurl.com/2os8fl.

So, it would be possible to implement a result_of that deduces the
correct return type in corner cases like your example without
decltype. But decltype is a much better all around solution.

Daniel


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