Hi all,
When writing a simple proto program to deal with fraction expressions
(just an exercise to get accustomed with proto library) we run into a
compiler error that we are not able to fix.
The aim of the exercise is to write a grammar to:
1) Remove all calls to a given function (named "Sim") in an expression:
'Sim(Sim(Sim(a)))' is transformed into 'a'. This is a simple variation
of the "remove-unary-plus" as found in the manual, and it works fine;
2) Remove all consecutive calls to Sim but one, so expressions like
'Sim(Sim(Sim(a)))' will turn out be 'Sim(a)'. This does not work with
gcc (4.3.2 and 4.3.4) and icc (11.1), but works fine with Visual Studio
(2008 and 2010). Boost 1.44 and 1.43, Windows and Linux.
The error gcc gives is:
minimalproto.cc: In function ‘int main()’:
minimalproto.cc:73: error: no matching function for call to
‘eval(boost::proto::exprns_::expr<boost::proto::tag::function,
boost::proto::argsns_::list2<const
simexpr<boost::proto::exprns_::expr<boost::proto::tag::terminal,
boost::proto::argsns_::term<simplifyfct>, 0l> >&, const
frac_calculator<boost::proto::exprns_::expr<boost::proto::tag::terminal,
boost::proto::argsns_::term<const frac&>, 0l> >&>, 2l>, frac_context&)’
....boost-1.43/include/boost/proto/eval.hpp:89: note: candidates are:
typename boost::proto::result_of::eval<Expr, Context>::type
boost::proto::eval(Expr&, Context&) [with Expr =
boost::proto::exprns_::expr<boost::proto::tag::function,
boost::proto::argsns_::list2<const
simexpr<boost::proto::exprns_::expr<boost::proto::tag::terminal,
boost::proto::argsns_::term<simplifyfct>, 0l> >&, const
frac_calculator<boost::proto::exprns_::expr<boost::proto::tag::terminal,
boost::proto::argsns_::term<const frac&>, 0l> >&>, 2l>, Context =
frac_context]
....boost-1.43/include/boost/proto/eval.hpp:98: note:
typename boost::proto::result_of::eval<Expr, Context>::type
boost::proto::eval(Expr&, const Context&) [with Expr =
boost::proto::exprns_::expr<boost::proto::tag::function,
boost::proto::argsns_::list2<const
simexpr<boost::proto::exprns_::expr<boost::proto::tag::terminal,
boost::proto::argsns_::term<simplifyfct>, 0l> >&, const
frac_calculator<boost::proto::exprns_::expr<boost::proto::tag::terminal,
boost::proto::argsns_::term<const frac&>, 0l> >&>, 2l>, Context =
frac_context]
Somebody knows what's going on?
Any insight will be highly appreciated.
Cheers,
Mauro.
#include <boost/proto/proto.hpp>
namespace proto = boost::proto;
namespace mpl = boost::mpl;
struct frac {};
struct simplifyfct
{
typedef frac result_type;
frac const & operator()(frac const & f) const { return f;}
};
template <typename Expr>
struct frac_calculator;
struct frac_domain
: proto::domain<proto::generator<frac_calculator> >
{};
template <typename EXPR>
struct simexpr
{
BOOST_PROTO_BASIC_EXTENDS(EXPR, simexpr, frac_domain)
BOOST_PROTO_EXTENDS_FUNCTION()
};
simexpr<proto::terminal<simplifyfct>::type> const sim = {{}};
struct frac_context : proto::callable_context<frac_context> {};
template<typename Expr>
struct frac_calculator
: proto::extends<Expr, frac_calculator<Expr>, frac_domain>
{
typedef proto::extends<Expr, frac_calculator<Expr>, frac_domain> base_type;
frac_calculator(Expr const &expr = Expr())
: base_type(expr)
{}
};
/* The following grammar works */
struct RemoveAllSim
: proto::or_<
proto::when<
proto::function<proto::terminal<simplifyfct>, RemoveAllSim>
, RemoveAllSim(proto::_right)
>
, proto::terminal<frac>
>
{};
/* The following grammar does not work */
struct RemoveSim
: proto::or_<
proto::when<
proto::function<proto::terminal<simplifyfct>,
proto::function<proto::terminal<simplifyfct>, proto::_> >
, RemoveSim(proto::_right)
>
, proto::function<proto::terminal<simplifyfct>, proto::_>
, proto::terminal<proto::_>
>
{};
int main () {
frac a, b;
frac_context C;
#define TESTEXPR (sim(sim(sim(sim(a)))))
frac c = proto::eval(TESTEXPR, C); // THIS WORKS!
c = proto::eval( RemoveAllSim()( TESTEXPR ) , C); // THIS WORKS!
c = proto::eval( RemoveSim()( TESTEXPR ) , C); // THIS DOES NOT WORK!
return 0;
}
_______________________________________________
proto mailing list
proto@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/proto