On 5/30/2012 4:22 PM, Karsten Ahnert wrote: > Next trial: > > template< typename I > struct placeholder : I {}; > > proto::terminal< placeholder< mpl::size_t< 0 > > >::type const arg1 = {}; > > proto::display_expr( > fusion::fold( > proto::flatten( arg1 ) , > proto::functional::make_terminal()( 1.0 ) , > proto::functional::make_multiplies() > ) > ); > > gives a compilation error: > > /boost/proto/fusion.hpp:86:20: error: no type named ‘proto_tag’ in > ‘const struct placeholder<mpl_::size_t<0ul> > > > It is difficult for me to figure out what happens here. Any ideas?
Right. proto::flatten uses the type of the top-most node to figure out how to flatten the expression tree. E.g., if you passed arg1 * 32, the top-most node is a multiplication, so it would produce a list [arg1, 32]. You're passing just a terminal, so it creates a 1-element list containing the value of the terminal: [placeholder<I>]. Passing this to proto::functional::make_multiplies results in the above error because it's expecting a proto expression. Try this: #include <string> #include <iostream> #include <boost/proto/proto.hpp> namespace mpl = boost::mpl; namespace proto = boost::proto; namespace fusion = boost::fusion; using proto::_; template< typename I > struct placeholder : I {}; proto::terminal< placeholder< mpl::size_t< 0 > > >::type const arg1 = {}; template< class Expr > void eval( const Expr &e ) { proto::display_expr( fusion::fold( proto::flatten( e ) , proto::functional::make_terminal()( 1.0 ) , proto::when<_, proto::_make_multiplies(proto::_byval(proto::_state), proto::_byval(_))>() ) ); } int main() { eval( 2 * arg1 * 42.0 * arg1 ); } It takes the multiplication tree, flattens it, and turns it back into a multiplication tree in reversed order. HTH, -- Eric Niebler BoostPro Computing http://www.boostpro.com _______________________________________________ proto mailing list proto@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/proto