Boost logo

Boost :

Subject: Re: [boost] [result_of, tr1] decltype and incomplete types
From: Daniel Walker (daniel.j.walker_at_[hidden])
Date: 2010-04-12 11:05:37


On Sun, Apr 11, 2010 at 5:47 PM, Eric Niebler <eric_at_[hidden]> wrote:
>
> On 4/11/2010 12:29 PM, Eric Niebler wrote:
>> On 4/11/2010 9:37 AM, Daniel Walker wrote:
>>> On Sat, Apr 10, 2010 at 7:50 PM, Eric Niebler <eric_at_[hidden]> wrote:
>>>> If Boost.TR1 advertises itself as an implementation of TR1, then it
>>>> should have an implementation of result_of that doesn't rely on
>>>> decltype. (Waiting for John to jump in here.) That way, libraries like
>>>> Proto that need the tr1 behavior (until decltype is fixed) can use
>>>> std::tr1::result_of from boost/tr1/functional.hpp and forget about it.
>>>> This should be possible in the 1.44 time frame and is a good long-term
>>>> solution.
>>>
>>> Agreed.
>>
>> Note that to make this happen, you'll need to coordinate with John. The
>> way Boost.TR1 works is like this:
>>
>> - If the platform implements <tr1/foo_header>, include it. Otherwise,
>> - Include <boost/foo_header.hpp> and bring boost::foo into the std::tr1
>> namespace with a using declaration.
>>
>> If boost::result_of sometimes uses decltype, the above won't work
>> because then std::tr1::result_of will sometimes use decltype. It seems
>> to me that <boost/utility/result_of.hpp> should expose a
>> boost::tr1_result_of that can be used by <boost/tr1/result_of.hpp> to
>> get the TR1 behavior regardless of whether decltype exists or not.
>
> I opened a ticket for this (milestone 1.44) and attached a patch:
> https://svn.boost.org/trac/boost/ticket/4084. I noticed that the
> decltype change to result_of was causing regression failures in TR1 by
> making the implementation of TR1's result_of non-compliant. The patch
> fixes the issue and adds a boost::tr1_result_of.

I like the idea and the patch looks good. How do I go about getting it
on trunk? I don't believe I have check-in rights.

>
> The regression test failures may be more evidence that the change to
> result_of was a bad idea (as well-intentioned as it may have seemed).
> This patch may not be the last word on the issue. I'm still
> uncomfortable with the change to boost::result_of, which is likely to
> break users' code. Perhaps we could place the new decltype
> implementation on a compile-time switch (BOOST_RESULT_OF_USE_DECLTYPE?)
> so that users can opt in. That wouldn't eliminate the need for
> boost::tr1_result_of or something like it, though.

Ultimately, boost::result_of should behave as intended whenever
possible; i.e. it should evaluate to the type of a call expression.
The fact that in c++03 it was possible for result_of to evaluate to a
type other than the type of a call expression is a bug. In c++0x, the
compiler can detect these situations and report them as errors. That's
a good thing.

Now, I understand that it's too much to ask before the 1.43 release
that boost compile without error or regression in c++0x mode on gcc or
msvc, so I agree with sweeping this problem under the rug for this
release. But in the future, it is reasonable to expect regressions
when porting boost to c++0x. One type of regression will be situations
when result_of was evaluated to a type other than the type of the call
expression. Usually, this will be due to an unintended programming
error, so correcting the problem will be an improvement. Sometimes, it
will be due to a quirk of the TR1 protocol; for example, allowing
result_of in context where the call expression type is incomplete, as
was the case with Proto. Perhaps, result_of is not the best solution
in Proto's situation, and Proto should specify return types in its
function signatures in some other way... Regardless, given available
technology, result_of should evaluate to the type of the call
expression; in c++0x the technology is available and result_of should
use it.

Daniel Walker


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