[fusion] transform a heterogeneous vector
In the example from the documentation : struct triple { typedef int result_type; int operator()(int t) const { return t * 3; }; }; ... assert(transform(make_vector(1,2,3), triple()) == make_vector(3,6,9)); ...all the elements have the same type. How can it work with heterogeneous vectors ? What would be typedef'ed to result_type ? Jean-Louis
Fusion uses boost::result_of to determine the return type of a call
expression. Therefore you just need to define a result-metafunction.
struct triple
{
template<typename Sig>
struct result;
template
...all the elements have the same type. How can it work with heterogeneous vectors ? What would be typedef'ed to result_type ?
Jean-Louis
Christopher Schmidt wrote:
Fusion uses boost::result_of to determine the return type of a call expression. Therefore you just need to define a result-metafunction. Thanks. It works. However two things bother me.
First there's the warning :
1>c:\program
files\boost\boost_1_39\boost\fusion\view\transform_view\detail\deref_impl.hpp(42)
: warning C4172: returning address of local variable or temporary
1> c:\program
files\boost\boost_1_39\boost\fusion\view\transform_view\detail\deref_impl.hpp(41)
: while compiling class template member function 'const int
&boost::fusion::extension::deref_implboost::fusion::transform_view_iterator_tag::apply<Iterator>::call(const
Iterator &)'
1> with
1> [
1>
Iterator=boost::fusion::transform_view_iterator
Comments inline ... Jean-Louis Leroy schrieb:
First there's the warning :
1>c:\program
files\boost\boost_1_39\boost\fusion\view\transform_view\detail\deref_impl.hpp(42)
: warning C4172: returning address of local variable or temporary 1> c:\program
etc etc etc
I assume you return the plain argument type (that is a reference) in
your triple2::result meta-function. If that's the case, simply wrap the
argument in a remove_reference.
E.g.
struct triple2
{
//...
template
Also, I see that transform returns a view. I need a proper vector that is distinct from the input vector. Here's a bit of context. I am building a recipient for one row in a database query. I have a vector of Exprs, one for each column in the select. Expr has a type member. I want to make a vector with an element for each Expr, initialized to the type's default value (as per type()).
I.e. something like this :
struct f { /* ... */ template<typename Expr> operator ()(Expr) { return typename Expr::type(); } typedef result_of::transform
::type row_type; row_type row; transform(select.exprs, row); // type of select.exprs is SelectList std::deque results; while (data) { for_each(row, read_fun(...)); results.push_back(row); } Alas row_type is going to be a view :-/
simply convert the view (type!) back to a vector using
fusion::result_of::as_vector.
using namespace boost::fusion;
result_of::as_vector
participants (2)
-
Christopher Schmidt
-
Jean-Louis Leroy