
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