fork download
  1. #include <iostream>
  2.  
  3. #define MAKE_OPERATOR(name, op) \
  4.   template <typename Lhs, typename Rhs> \
  5.   struct name##_ { \
  6.   Lhs lhs; Rhs rhs; \
  7.   friend std::ostream& operator<<(std::ostream& os, name##_ const& n) \
  8.   { return os << '(' << n.lhs << #op << n.rhs << ')'; } \
  9.   friend auto eval(name##_ const& n) -> decltype(eval(n.lhs) op eval(n.rhs)) \
  10.   { return eval(n.lhs) op eval(n.rhs); } \
  11.   }; \
  12.   template <typename Lhs, typename Rhs, typename Res=name##_<Lhs,Rhs> > \
  13.   Res name(Lhs const& lhs, Rhs const& rhs) { return Res{lhs, rhs}; }
  14.  
  15. double eval(double d) { return d; }
  16. MAKE_OPERATOR(prod, *)
  17. MAKE_OPERATOR(sum, +)
  18. MAKE_OPERATOR(div, /)
  19.  
  20. int main()
  21. {
  22. auto a = prod(sum(sum(2, 3), 1), 5);
  23. std::cout << a << " = " << eval(a) << '\n';
  24.  
  25. auto b = div(sum(28, 2), prod(5, 2));
  26. std::cout << b << " = " << eval(b) << '\n';
  27. }
  28.  
  29.  
Success #stdin #stdout 0s 2884KB
stdin
Standard input is empty
stdout
(((2+3)+1)*5) = 30
((28+2)/(5*2)) = 3