Boost logo

Boost :

Subject: Re: [boost] [result_of] Allow result_of to work with C++11 lambdas
From: Daniel Walker (daniel.j.walker_at_[hidden])
Date: 2013-04-27 18:38:43


On Apr 27, 2013, at 12:40 PM, "Peter Dimov" <lists_at_[hidden]> wrote:

> Daniel Walker wrote:
>> On Apr 21, 2013, at 10:36 PM, Peter Dimov <lists_at_[hidden]> wrote:
>>
>> > I can't think of a reason to ever use TR1 (and whichever version of > result_of) in C++11. Even less so in C++14, which will have deduced > return types unless the N3638 formal motion failed, and I very much hope > it did not.
>>
>> Agreed, and we recommend in the boost::result_of documentation that C++11 users use std::result_of rather than boost::result_of.
>
> I actually meant that C++11 users should use decltype directly rather than result_of.
>
> A library that wanted to support both would do something like
>
> template<...>
>
> #if C++11
>
> auto f(...) -> decltype(...)
>
> #else
>
> boost::result_of<...>::type f(...)
>
> #endif
>
> { ... }
>
> That's not very nice as it forces you to write everything twice, but it keeps C++11 users isolated from anything C++03-related. In particular, it no longer matters whether boost::result_of works with lambdas. (Well... it could matter if decltype is not N32whatever but lambdas work fine, but ideally, it shouldn't.)

Yeah, this could work for some folks in some situations. But there are also all those containers out there that have been generated to store results from some function. I know I've seen code like the following over the years.

template<class ForwardIterator, class AuxilaryFunction>
class component
{
    typedef std::vector<
        typename boost::result_of<
            AuxilaryFunction(
                typename std::iterator_traits<
                    ForwardIterator
>::value_type
            )
>::type
> auxilary_results_vector;

    auxilary_results_vector aux_results;
    AuxilaryFunction aux_function;

public:
    void initialize(AuxilaryFunction f) { aux_function = f; }

    template<class OutputIterator>
    void process(ForwardIterator first, ForwardIterator last, OutputIterator out) {
        for(ForwardIterator i = first; i != last; ++i) {
            aux_results.push_back(aux_function(*i));
            // etc.
        }
        // etc.
    }
};

Someone with code like this could abandon C++03 entirely, if they wanted to, with s/boost::result_of/std::result_of/. Or they could replace result_of with an equivalent decltype expression, though this could get cumbersome and verbose. Or they could continue using boost::result_of for more options regarding compiler portability without having to change a line of code.

- Daniel


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