Subject: Re: [boost] [result_of, tr1] decltype and incomplete types
From: Daniel Walker (daniel.j.walker_at_[hidden])
Date: 2010-04-12 19:02:25
On Mon, Apr 12, 2010 at 1:28 PM, Eric Niebler <eric_at_[hidden]> wrote:
> On 4/12/2010 8:05 AM, Daniel Walker wrote:
>> On Sun, Apr 11, 2010 at 5:47 PM, Eric Niebler <eric_at_[hidden]> wrote:
>>> 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.
> This is a strident position ... and wrong. Intention has nothing to do
> with it. Boost::result_of should behave as *specified*. The current
> documentation for boost::result_of specify it to use the TR1 result_of
> protocol. Users have come to rely on it. The TR1 behavior is not a bug.
> It's a standard.
I don't mean to be stridently wrong. :) Let me try to explain. The
boost::result_of documentation says the following:
"The class template result_of helps determine the type of a call
expression. Given an lvalue f of type F and lvalues t1, t2, ..., tN of
types T1, T2, ..., TN, respectively, the type result_of<F(T1, T2, ...,
TN)>::type defines the result type of the expression f(t1, t2,
In the strictest sense, this is only true in TR1 if F is a function
pointer, function reference or member function pointer. If F is a
class type, result_of<F(T1, T2, ..., TN)>::type could be any type and
may have nothing to do with the expression f(t1, t2, ...,tN),
depending on whether F::result<> meets the "intention" of the
specification. result_of is specified to give the type of
f(t1, t2, ...,tN). If, for whatever reason, it is not the type of
f(t1, t2, ...,tN), then that is a "bug," in some sense. In c++0x,
result_of can treat class types the same way as function pointers,
function references and member function pointers; i.e. it can give the
type of f(t1, t2, ...,tN) for any F, so this sort of bug is no longer
> And if you want to talk about *standard* specifications, there are 2 to
> choose from (or will be soon): TR1 and C++0x. One can be implemented
> with complete fidelity on every major supported compiler. The other can
> only be supported on the newest compilers and is still in flux due to a
> bug in the specification of decltype. I think going with the second is
> premature, even if you forget about the LOCs you'll break.
> Intentions and specifications aside, you are now the maintainer of one
> of the most heavily used and essential pieces of Boost infrastructure.
> Not breaking code should be a factor in your decisions. If you want to
> change behavior, you need a migration path. Putting the new
> (experimental and buggy) behavior on a switch so users can opt in is a
> reasonable first step. It should be accompanied with documentation,
> release notes, and an effort to educate boost developers and users about
> ways to find their portability/migration issues so that their code works
> with a decltype-based result_of. We may decide to hold here for a few
> releases, or until vendors start shipping non-broken decltype
> implementations. Only after folks have had sufficient warning and time
> to adapt could we think about making decltype the default.
I agree with the priorities you've expressed, and I'm glad you've
pressed the issue here and on CWG. I think we're coming to a better
understanding of things, now, and we can continue ironing out these
issues after 1.43.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk