#include //-------------------------------------------------- // Applicative templates. template struct bin_mul {static T apply(T a,T b) {return a*b;}}; template struct bin_add {static T apply(T a,T b) {return a+b;}}; template class NumExpr { const T& x; public: NumExpr(const T& _x): x(_x) {} T get() const {return x;} }; template class Expr { ET /* & */ sub_expr; public: Expr(ET _sub_expr): sub_expr(_sub_expr) {} T get() const {return sub_expr.get();} }; // Binary expression template class BinExpr { ET1 /* & */ sub_expr1; ET2 /* & */ sub_expr2; public: BinExpr(ET1 _sub_expr1, ET2 _sub_expr2): sub_expr1(_sub_expr1), sub_expr2(_sub_expr2) {} T get() const {return OT::apply(sub_expr1.get(),sub_expr2.get());} }; //---------------------------------------------------------------------- // Operators. // Unfortunately, we need binary operators for each combination // of two operands of type NumExpr<...> or Expr<...> template Expr< BinExpr,NumExpr,bin_add, T>,T > operator + (NumExpr a, NumExpr b) { typedef BinExpr,NumExpr,bin_add,T > Expr_T; return Expr(Expr_T(a,b)); } template Expr< BinExpr,NumExpr, bin_add,T>,T > operator + (Expr a, NumExpr b) { typedef BinExpr< Expr , NumExpr, bin_add,T > Expr_T; return Expr(Expr_T(a,b)); } template Expr< BinExpr,Expr, bin_add,T>,T > operator + (NumExpr a, Expr b) { typedef BinExpr< NumExpr, Expr, bin_add,T > Expr_T; return Expr(Expr_T(a,b)); } template Expr< BinExpr,Expr, bin_add,T>,T> operator + (Expr a, Expr b) { typedef BinExpr< Expr , Expr, bin_add,T > Expr_T; return Expr(Expr_T(a,b)); } template Expr< BinExpr,NumExpr,bin_mul,T>,T> operator * (NumExpr a, NumExpr b) { typedef BinExpr,NumExpr,bin_mul,T > Expr_T; return Expr(Expr_T(a,b)); } template Expr< BinExpr,NumExpr, bin_mul,T >,T > operator * (Expr a, NumExpr b) { typedef BinExpr< Expr , NumExpr, bin_mul,T > Expr_T; return Expr(Expr_T(a,b)); } template Expr< BinExpr, Expr, bin_mul,T >,T > operator * (NumExpr a, Expr b) { typedef BinExpr< NumExpr, Expr , bin_mul,T > Expr_T; return Expr(Expr_T(a,b)); } template Expr< BinExpr, Expr, bin_mul,T>,T> operator * (Expr a, Expr b) { typedef BinExpr< Expr, Expr, bin_mul,T > Expr_T; return Expr(Expr_T(a,b)); } template inline T get(Expr e) {return e.get();} //---------------------------------------------------------------------- // Try it out main() { double _a = 3.2; double _b = 4.1; double _c = 2.2; double _d = 3.3; double _e = 8.9; NumExpr a(_a); NumExpr b(_b); NumExpr c(_c); NumExpr d(_d); NumExpr e(_e); cout << get(a + ( b + c * e ) * d) << endl; cout << (_a + ( _b + _c * _e ) * _d) << endl; }