
As Joel pointed out already, you need to wrap your expression templates to give them their domain specific meaning. In your case, the cast operator. This cast operator would need to have a context, or preferably a transform (a transform is a grammar is a transform) to evaluate your expression to std::complex<double>. See:http://www.boost.org/doc/libs/1_45_0/doc/html/proto/users_guide.html#... for an example with contexts.
The steps to define a grammar that does the transformation are the following: 1) define a grammar that matches your expression
ok, at the level I am working it seem that the following grammar is what I need. note that it is not recursive and it is a completely rigid structure. struct complex_cartesian_grammar : proto::plus< proto::terminal<double>, proto::multiplies< proto::terminal<double>, proto::terminal<i_tag> > >{}; (complete code at the end)
2) attach semantic actions, step by step to your grammar rules
not so fast, how do I do that? I also defined the "domain" struct complex_cartesian_domain : proto::domain< proto::generator< complex_cartesian_expr >, complex_cartesian_grammar >{}; I still have to somehow connect the define grammar with the expression itself. how? I also understand that the expression convertible to std::complex<double> must match double + double*i (the simple grammar) but again I don't understand how to do it. What follows is the complete code I have far. -- Thank you | Alfredo #include <boost/proto/core.hpp> #include <complex> namespace pretty{ namespace proto = boost::proto; struct i_tag{}; proto::terminal< i_tag >::type const i = {{}}; template< typename Expr > struct complex_cartesian_expr; struct complex_cartesian_grammar : proto::plus< proto::terminal<double>, proto::multiplies< proto::terminal<double>, proto::terminal<i_tag> > >{}; struct complex_cartesian_domain : proto::domain< proto::generator< complex_cartesian_expr >, complex_cartesian_grammar >{}; template<typename Expr> struct complex_cartesian_expr : proto::extends< Expr, complex_cartesian_expr< Expr >, complex_cartesian_domain >{ complex_cartesian_expr( Expr const & expr = Expr() ) : proto::extends< Expr, complex_cartesian_expr< Expr >, complex_cartesian_domain >( expr ){} template<typename T> operator std::complex<T>() const{ return std::complex<T>( proto::value( proto::child_c<1>(*this) ), proto::value( proto::child_c<1>(proto::child_c<2>(*this)) ) ) ; } }; } int main(){ using namespace pretty; std::complex<double> z = 4. + 5.*i; return 0; }