|
Boost : |
From: Daniel Walker (daniel.j.walker_at_[hidden])
Date: 2007-03-20 11:23:07
Hello,
I noticed that result_of doesn't handle functors created by the Boost
Lambda Library. For example,
$ g++ -dumpversion
4.1.2
$ cat result_of_error.cpp
#include <boost/lambda/lambda.hpp>
#include <boost/utility/result_of.hpp>
using namespace boost;
template<class Functor, class Arg1, class Arg2>
void f(Functor const&, Arg1 const&, Arg2 const&)
{
typedef typename result_of<
Functor(Arg1, Arg2)
>::type result_type;
}
int main()
{
using namespace lambda;
int x = 0, y = 0;
f(ret<int>(_1 + _2), x, y);
}
$ g++ -I./boost result_of_error.cpp 2>&1 | perl gSTLFilt.pl
./boost/boost/utility/result_of.hpp:68: error: no class template named 'result'
in 'class boost::lambda::lambda_functor<
...
>'
...
$
Among Boost libraries, there are at least two ways for function
objects to expose return types that are dependent on the types of
their arguments.
1) result_of instructs users to expose a template result<F(ARG1, ..., ARGN)>.
2) Boost.Lambda instructs users to expose a template sig<tuple<ARG1,
..., ARGN>, and it also uses this convention internally.
It might be nice to unify these two approaches one day or perhaps
simplify the matter by implementing result_of in terms of the Boost
Typeof Library along the lines of Douglas Gregor's "Looking Ahead"
section in his 2003 paper, http://tinyurl.com/2nf5ym. But I figure in
the mean time why not have result_of support both of the current
approaches? If the functor has a nested sig template use that,
otherwise try to use a nested result template.
There's one additional caveat for supporting lambda expressions. A
zero arity lambda functor expose its result type through the typedef
nullary_return_type. This can be handle in result_of by providing a
partial specialization of result_of_void_impl for the template class
lambda::lambda_functor.
The attached patch adds support for sig in functors and nullary lambda
functors. Apply with 'patch -p0 < djw_result_of.patch' from the boost
root directory. It depends on the has_template_xxx patch I submitted
previously (http://tinyurl.com/35x5z5).
Also, if has_template_xxx is unsupported for a particular compiler the
patch supplies a partial specialization of result_of_nested_result for
lambda::lambda_functor. That way at least lambda expressions can be
supported if not user defined functors that employ the Boost Lambda
Library's convention of specifying result types. I ran the Boost
Utility Library test suite and everthing passed. Let me know and I can
provide documentation and tests.
Thanks!
Daniel Walker
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk