Boost logo

Boost :

From: Eric Niebler (eric_at_[hidden])
Date: 2007-05-21 10:28:19


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.

> There's no such problem with the A1 overload since, as a template, it's not
> instantiated unless used.
>
> With variadic templates a special case is no longer necessary and I believe
> that the C++0x result_of no longer has one.

I guess if the problem is going away, then that's something, I guess.
Besides, the wording of the TR seems to allow me to force the issue, with:

   template<>
   struct result_of< bar() >
     : bar::result< bar() >
   {};

Ditto for the cv-qualifications of bar. I may end up doing that.

Thanks,

-- 
Eric Niebler
Boost Consulting
www.boost-consulting.com

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