Boost logo

Boost Users :

Subject: Re: [Boost-users] [Range & c++0x Lambdas] Can this be done?
From: Eric Niebler (eric_at_[hidden])
Date: 2012-11-29 11:29:10


On 11/28/2012 10:37 PM, Jeffrey Lee Hellrung, Jr. wrote:
> On Wed, Nov 28, 2012 at 10:26 PM, Eric Niebler wrote:
>>
>> On 11/22/2012 11:31 AM, Jeffrey Lee Hellrung, Jr. wrote:
>>> Maybe this is what you did, so I might not be suggesting something
>>> new,
>>> but... Perhaps boost::result_of could have an extra conditional logic
>>> branch added to it:
>>> - If F::result_type exists, return F::result_type;
>>> - Else:
>>> - If BOOST_NO_CXX11_DECLTYPE, return F::result< F ( Args... ) >
>>> - Else, if F::result<> exists, return F::result< F ( Args... ) >
>>> - Else return decltype( declval<F>() ( declval< Args >()... ) )
>>
>> C++11 defines exactly what result_of does, as did the TR1 spec before
>> it. Making boost::result_of do something different would be
>> surprising, IMO.
>>
>> If you want to use C++11 lambdas with boost::result_of, the most
>> portable solution is with an adapter, as has been suggested elsewhere in
>> this thread. Not ideal, but it works.
>
>
> I'm only suggesting to extend result_of for C++11 lambdas (and,
> incidentally, other callable types) when result_of wouldn't know what to
> do otherwise. Do you mean it would be surprising for result_of to work
> when it would be expected to fail? Maybe there's something subtle I'm
> missing here.
>
> I'm supposing in this, of course, that there are compilers which support
> lambdas and have some form of decltype sufficient for lambdas but
> insufficient to be the primary implementation of result_of (i.e., must
> use TR1-style for the primary implementation). That's quite a few
> compilers presently, right?

Here's the surprising part:

> - If F::result_type exists, return F::result_type;
> - Else:
> - If BOOST_NO_CXX11_DECLTYPE, return F::result< F ( Args... ) >
> - Else, if F::result<> exists, return F::result< F ( Args... ) >
> - Else return decltype( declval<F>() ( declval< Args >()... ) )

The way I read this is that F::result_type (and F::result<>) is taking
precedence over decltype. AFAICT, you're suggesting that result_of *not*
compute the actual return type of a function object, but rather return
the declared result type, even if it's wrong.

In moving to a decltype-based result_of, we discovered just how many
function objects in boost were lying about their return types via the
TR1 result_of protocol. Now that we have decltype, we can get the right
answer always. I would be *immensely* surprised if result_of ever got
the wrong answer on a compiler that had decltype.

And btw, I don't think lambdas are required to have a nested result_type
typedef, are they? So what benefit does changing the protocol have?
Wouldn't you still need a wrapper anyway?

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

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net