Boost logo

Boost Users :

Subject: Re: [Boost-users] [phoenix] v2 to v3 transition of extension mechanism
From: Thomas Heller (thom.heller_at_[hidden])
Date: 2011-04-13 15:13:14


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/html/phoenix/examples/adding_an_expression.html)

Your browser is pointing to the wrong URL, use that one:
https://svn.boost.org/svn/boost/trunk/libs/phoenix/doc/html/phoenix/examples/adding_an_expression.html

> 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.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net