$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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