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