Boost logo

Boost :

From: Daniel Walker (daniel.j.walker_at_[hidden])
Date: 2007-03-22 09:53:26


Hello,

It was pointed out to me in another thread (http://tinyurl.com/2l22av)
that the following is an incorrect usage of result_of.

On 3/21/07, Daniel Walker <daniel.j.walker_at_[hidden]> wrote:
>
> struct result_functor {
> // Define a result trait such that result<F(F,A1)>::type is A1.
> BOOST_FIXED_ARITY_FUNCTOR_RESULT(2, A1)
>
> template<class Arg>
> typename result<result_functor(result_functor, Arg)>::type
> operator()(Arg const& a) const
> {
> return a;
> }
> };
>
[...]
>
> template<class F, class Arg>
> typename result_of<F(F, Arg)>::type
> f(F const& functor, Arg& a)
> {
> return functor(a);
> }
>
[...]
>
> result_of<
> sig_functor(sig_functor, value_type)
> >::type z = f(sig_f, x);

The result of documentation states:

"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,
...,tN)."

So, obviously the usage above is wrong.

The reason it compiled (using gcc 4.1) was due to a misunderstanding I
had in converting result<> to sig<> and vice versa. I did ...

sig<tuple<F, T1, T2, ..., TN> > <--> result<F(F, T1, T2, ..., TN)>

It should have been.

sig<tuple<F, T1, T2, ..., TN> > <--> result<F(T1, T2, ..., TN)>

The attached patch is a revision of the first that corrects this
problem. Also, I added a check for the availability of result_of
through BOOST_NO_RESULT_OF and left the behavior unchanged for
platforms that result_of doesn't support.

With this revised patch you can do.

#include <boost/lambda/bind.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/utility/result_of.hpp>
using namespace boost;

struct result_functor {
    // Define a result trait such that result<F(A0)>::type is A0.
    BOOST_FIXED_ARITY_FUNCTOR_RESULT(1, A0)

    template<class Arg>
    typename result<result_functor(Arg)>::type
    operator()(Arg const& a) const
    {
        return a;
    }
};

struct sig_functor {
    template<class Args>
    struct sig {
        typedef typename tuples::element<1, Args>::type type;
    };

    template<class Arg>
    typename sig<tuple<sig_functor, Arg> >::type
    operator()(Arg const& a) const
    {
        return a;
    }
};

template<class F, class Arg>
typename result_of<F(Arg)>::type
f(F const& functor, Arg& a)
{
    return functor(a);
}

int main()
{
    using namespace boost::lambda;

    typedef char value_type;
    value_type x;
    result_functor result_f;
    value_type y = f(bind(result_f, _1), x);
    sig_functor sig_f;
    value_type z = f(bind(sig_f, _1), x);
}

And additionally with my previously submited result_of patch ...

    result_of<
        sig_functor(value_type)
>::type z = f(sig_f, x);

I ran the lambda regressions again and they passed. Let me know if you
see more problems.

Thanks!
Daniel




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