On Tuesday, April 12, 2011 07:59:13 AM alfC wrote:
Hi, I am updating some of my code to use Phoenix3 instead of Phoenix2.
For example in Phoenix2 I used to have this extension to support 'cos(...)' expressions:
namespace boost{ namespace phoenix{ struct cos_eval{ template<class Env, typename Arg_> struct result{typedef double type;}; template<class RT, typename Env, typename Arg_> static RT eval(Env const& env, Arg_ const& arg_){ return cos(arg_.eval(env)); } }; template<typename Arg_> void cos(Arg_ const& arg_){ return compose<cos_eval>(arg_); } }}
In Phoenix3, if I followed things correctly (from here
https://svn.boost.org/svn/boost/sandbox/SOC/2010/phoenix3/libs/phoenix/doc/h...) Your browser is pointing to the wrong URL, use that one: https://svn.boost.org/svn/boost/trunk/libs/phoenix/doc/html/phoenix/examples...
the new framework ask for the following, which doesn't work. The error (see at end) is difficult to decipher. What am I missing to implement this simple expression extension? -- Thanks.
You did everything right ... conforming to the old docs ... however I changed one little detail. Explanation and fix inlined in the code below.
namespace boost { namespace phoenix { struct cos_eval{ typedef double result_type;
Here is the change:
template <typename Context, typename Arg> result_type operator()(Context const& ctx, Arg const& arg) const{ return std::cos(eval(arg, ctx)); }
Change it to: template <typename Arg, typename Context> result_type operator()(Arg const& arg, Context const& ctx) const{ return std::cos(eval(arg, ctx)); } I moved the Context argument to the end of the argument list so it gets more consistent to the eval function. eval takes the context as the last argument because its the proto state, thus its the second parameter. The rest of your code looks good. Sorry for that little inconvenience.
usr/include/boost/proto/matches.hpp:846:13: error: no type named ‘proto_tag’ in ‘const struct boost::phoenix::vector2<boost::phoenix::vector2<const
boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::tag::cos_,
boost::proto::argsns_::list1<boost::phoenix::actor<boost::proto::exprns_::expr<boost::proto::tag::terminal,
boost::proto::argsns_::term<boost::phoenix::argument<1> >, 0l> > >, 1l> >*, double&>&, const boost::phoenix::default_actions&>’ compilation terminated due to -Wfatal-errors.
The error you got here is basically saying: The context is not a proto expression. Since it was passed as first argument to your function it was assumed to be one, which lead to the error. FWIW, phoenix no has a cmath module (note: this file moved): #include <boost/phoenix/stl/cmath.hpp> and you get all functions from cmath in the lazy version.