Boost logo

Boost :

Subject: Re: [boost] [result_of] Make `cpp0x_result_of_impl` public
From: Eric Niebler (eric_at_[hidden])
Date: 2012-03-27 20:28:34


On 3/27/2012 4:13 PM, Daniel Walker wrote:
> On Mar 27, 2012, at 4:55 PM, Eric Niebler wrote:
>
>> On 3/27/2012 1:10 PM, Nathan Ridge wrote:
>>>
>>>> Date: Tue, 27 Mar 2012 13:00:19 -0700
>>>> From: eric_at_[hidden]
>>>> To: daniel.j.walker_at_[hidden]
>>>> CC: boost_at_[hidden]
>>>> Subject: Re: [boost] [result_of] Make `cpp0x_result_of_impl` public
>>>>
>>>> On 3/27/2012 12:48 PM, Daniel Walker wrote:
>>>>>
>>>>> On Mar 27, 2012, at 2:53 PM, Eric Niebler wrote:
>>>>>
>>>>>> On 3/27/2012 11:49 AM, Daniel Walker wrote:
>>>>>>>
>>>>>>> On Mar 27, 2012, at 1:35 PM, Eric Niebler wrote:
>>>>>>>
>>>>>>>> On 3/24/2012 1:52 AM, Michel Morin wrote:
>>>>>>>>> There are two implementations of boost::result_of: a TR1-style
>>>>>>>>> implementation and a decltype-based implementation. While
>>>>>>>>> the TR1-style implementation has a public interface `boost::tr1_result_of`,
>>>>>>>>> decltype-based one doesn't have a public interface.
>>>>>>>>
>>>>>>>> Yes, I'm the one responsible for this change.
>>>>>>>>
>>>>>>>>> By defining BOOST_RESULT_OF_USE_DECLTYPE,
>>>>>>>>> boost::result_of use decltype-based implementation.
>>>>>>>>> But this is not always a viable solution, since this breaks
>>>>>>>>> some Boost libraries.
>>>>>>>>>
>>>>>>>>> So how about adding `boost::cxx11_result_of` as public interface
>>>>>>>>> of the decltype-based implementation?
>>>>>>>>> Attached a patch to add `boost::cxx11_result_of`.
>>>>>>>>> (This patch also changes the name of `cpp0x_result_of_impl`
>>>>>>>>> to `cxx11_result_of_impl` to reflect the recent discussion on
>>>>>>>>> the cpp/cxx naming.)
>>>>>>>>
>>>>>>>> The patch looks fine, and I guess I'm as qualified to apply it as
>>>>>>>> anybody. But it doesn't have docs and tests. Care to address that? The
>>>>>>>> docs probably only need a line or two, and you can copy the tests for
>>>>>>>> tr1_result_of.
>>>>>>>>
>>>>>>>
>>>>>>> I'm not sure that I agree that cxx11_result_of is a good idea. The plan was for boost::result_of to become a C++11 result_of as soon as we're comfortable flicking the switch so that it's on by default (on platforms that can support it). Michel, do you just want a C++11 result_of that works out-of-the-box or do you really need a separate interface in addition to boost::result_of?
>>>>>>
>>>>>> There are places where a decltype-based result_of is safe, even if N3256
>>>>>> isn't implemented. In that case, cxx11_result_of would be the only
>>>>>> option, since boost::result_of would still defer to tr1_result_of.
>>>>>
>>>>> I would prefer, rather than fracturing the API, that we provide decltype-based boost::result_of by default on compilers that provide a reasonable decltype implementation, even if it's not fully N3256 compliant, with a well-documented caveat that boost::result_of depends on the compiler's decltype. For those who would rather have TR1 result_of than a result_of using non-N3256 decltype, they can use the existing tr1::result_of or boost::tr1_result_of.
>>>>
>>>> This will badly and needlessly break valid code both within boost and in
>>>> the wild for a large segment of Boost's users. Why would you prefer
>>>> doing that than taking the safer course?
>>>
>>> Why not implement boost::result_of using decltype only on compilers that have N3256 decltype,
>>> and give users with compilers that have non-N3256 decltype the option of turning on
>>> BOOST_RESULT_OF_USE_DECLTYPE?
>
> I think Nate's suggestion is reasonable. Boost libraries which require N3256 can use tr1::result_of, so that they are more portable to non-standard compilers and do not break as easily when users request decltype-based boost::result_of, which, of course, is a perfectly reasonable request.

I should say that Nate's suggestion *is* reasonable, but (IIUC) he's not
suggesting turning on decltype-based result_of for non-N3256 compilers,
as you are (right?). His suggestion is pretty much The Plan and has been
all along. He's merely questioning the need for an additional
cxx11_result_of. I think it has value for people with who want to
selectively use decltype-based result_of in their code where they know
it is safe, regardless of whether a compiler implements N3256.

But now that I rethink this, the use of cxx11_result_of anywhere
necessarily makes such code non-portable to c++03 compilers, so it'll
probably never be used within Boost. It could only be used (a) by
Boost's users who (b) have compilers that support decltype and (c) don't
support N3256 and (d) don't have a std::result_of that uses decltype.
I'm pretty sure that's exactly zero people.

So I'm flip-flopping. Nate's suggestion is correct.

As for your suggestion that Boost libraries can use tr1_result_of where
necessary, I agree. Proto already does this.

>> Because BOOST_RESULT_OF_USE_DECLTYPE is a big hammer, and if someone
>> uses that hammer with a non-N3256 compiler, there will be much
>> collateral damage. Innocent bystanders. Think of the children.
>
> boost::result_of can guarantee backwards compatibility with TR1 in situations where the TR1 result_of protocol was used to generate the type of the given call-expression. If the TR1 protocol was used to generate an incomplete type, then boost::result_of can't make that guarantee on non-N3256 compliant compilers. I think most users would find this completely acceptable.

Again, I ask why? Why, when there is a less risky path forward? When we
specifically added a feature test for compliance with N3256 for this
very purpose?

-- 
Eric Niebler
BoostPro Computing
http://www.boostpro.com

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