![]() |
Home | Libraries | People | FAQ | More |
Synopsis:
namespace proto { namespace result_of { // A metafunction for calculating the return // type of proto::eval() given certain Expr // and Context types. template<typename Expr, typename Context> struct eval { typedef typename Context::template eval<Expr>::result_type type; }; } namespace functional { // A callable function object type for evaluating // a Proto expression with a certain context. struct eval : callable { template<typename Sig> struct result; template<typename Expr, typename Context> typename proto::result_of::eval<Expr, Context>::type operator ()(Expr &expr, Context &context) const; template<typename Expr, typename Context> typename proto::result_of::eval<Expr, Context>::type operator ()(Expr &expr, Context const &context) const; }; } template<typename Expr, typename Context> typename proto::result_of::eval<Expr, Context>::type eval(Expr &expr, Context &context); template<typename Expr, typename Context> typename proto::result_of::eval<Expr, Context>::type eval(Expr &expr, Context const &context); }
Given an expression and an evaluation context, using proto::eval()
is quite simple. Simply pass the expression and the context to proto::eval()
and it does the rest
and returns the result. You can use the eval<>
metafunction in the proto::result_of
namespace to compute the
return type of proto::eval()
. The following demonstrates
a use of proto::eval()
:
template<typename Expr> typename proto::result_of::eval<Expr const, MyContext>::type MyEvaluate(Expr const &expr) { // Some user-defined context type MyContext ctx; // Evaluate an expression with the context return proto::eval(expr, ctx); }
What proto::eval()
does is also very simple.
It defers most of the work to the context itself. Here essentially is
the implementation of proto::eval()
:
// eval() dispatches to a nested "eval<>" function // object within the Context: template<typename Expr, typename Context> typename Context::template eval<Expr>::result_type eval(Expr &expr, Context &ctx) { typename Context::template eval<Expr> eval_fun; return eval_fun(expr, ctx); }
Really, proto::eval()
is nothing more than
a thin wrapper that dispatches to the appropriate handler within the
context class. In the next section, we'll see how to implement a context
class from scratch.