From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2007-07-12 17:04:35


shunsuke wrote:
> Hi,
>
> cvs head can't compile this.
>
> #include <boost/fusion/include/as_vector.hpp>
> #include <boost/fusion/include/transform_view.hpp>
> #include <boost/fusion/include/vector.hpp>
>
> struct identity
> {
> template<class FunCall>
> struct result;
>
> template<class Fun>
> struct result<Fun(int&)>
> {
> typedef int& type;
> };
>
> int& operator()(int& i) const
> {
> return i;
> }
> };
>
> int main()
> {
> typedef boost::fusion::vector<int, int> from_t;
> from_t from;
> boost::fusion::transform_view<from_t, ::identity> v(from, ::identity());
>
> // error.
> boost::fusion::as_vector(v);
> }
>
> fusion::as_vector calls result_of::value_of.
> Then, <boost/fusion/sequence/view/transform_view/detail/value_of_impl.hpp>
> calls result_of::value_of. So, non-reference int is passed to ::identity::result.
> I'm not sure which is wrong, as_vector or transform_view.

Confirmed. It seems 'transform_view' needs a 'remove_reference'
somewhere. There might be other places with similar issues. I'll check
on it tomorrow.

It's wrong to have the signature for result_of contain references:

The result_of specification says the parameter types in the signature
type should be interpreted as types of L-Value arguments used in a call
expression (cited from memory).

To understand why this strategy makes sense let's consider a simple call
site:

     identity i;
     int j;
     result_of<identity(int)>::type k = i(j);

It should compile fine. I can't (and don't want to) know that the
L-Value 'j' is bound to a reference!

Even if the argument actually /is/ a reference it doesn't make much
sense to tell result_of about it - it makes no difference for the
outcome and just makes nested 'result' metafunctions tedious (if not
impossible) to implement.

Regards,
Tobias