#include <iostream> #include <cmath> // for std::pow template<typename Data> struct sum{ Data operator()(const Data & a, const Data & b ){ return a+b; } }; template<typename Data> struct multiply{ Data operator()(const Data & a, const Data & b ){ return a*b; } }; template<typename Result> struct divide{ Result operator()(const Result & a, const Result & b ){ return a/b; } }; template<typename Result> struct nroot{ Result operator()(const Result & a, const Result & b ){ return std::pow(a,1.0/b); } }; template<typename Data, typename Result, typename IncrOp, typename ResOp, int InitPar=0 > class mean{ public: // in C++98 typedef Data data_type; typedef Result result_type; using data_type=Data; using result_type=Result; using incrop_type=IncrOp; using resop_type=ResOp; mean(): ncount_{}, rvalue_{static_cast<data_type>(InitPar)}, mean_{} {}; void increment(Data d){ ncount_++; rvalue_=increment_(rvalue_,d); result_type rtemp=static_cast<result_type>(rvalue_); result_type ntemp=static_cast<result_type>(ncount_); mean_=result_(rtemp,ntemp); } result_type get_ave() const { return mean_;} private: IncrOp increment_; ResOp result_; Data ncount_; Data rvalue_; Result mean_; }; int main(){ // Since C++11 using data_type=int; using result_type=double; using sum_type=sum<data_type>; using multiply_type=multiply<data_type>; using divide_type=divide<result_type>; using nroot_type=nroot<result_type>; using arithmetic_type=mean<data_type,result_type,sum_type,divide_type>; using geometrical_type=mean<data_type,result_type,multiply_type,nroot_type,1>; arithmetic_type a; geometrical_type b; data_type indata{}; std::cout <<"Enter values [Ctrl-D to finish]: " <<std::endl; while(std::cin>>indata){ a.increment(indata); b.increment(indata); } std::cout << " Arithmetic mean: " << a.get_ave() << "\n Geometrical mean: " << b.get_ave() << std::endl; return 0; }