Skip to content
Snippets Groups Projects
Commit 0427e12a authored by Francesco Saverio Cafagna's avatar Francesco Saverio Cafagna
Browse files

Adding abstract mean with functors

parent c5eb81d7
No related branches found
No related tags found
No related merge requests found
#ifndef FUNCTORS_H
#define FUNCTORS_H
#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);
}
};
#endif // FUNCTORS_H
\ No newline at end of file
#ifndef CLASS_MEAN_TEMPLATE_H_
#define CLASS_MEAN_TEMPLATE_H_
#include <iostream>
template<typename Data, typename Result> class mean{
public:
using value_type=Data;
using result_type=Result;
mean(){};
virtual ~mean(){};
virtual mean & add_data(value_type d) = 0;
virtual result_type get_mean() const =0;
virtual void print(std::ostream & o=std::cout, const char term='\n') const =0;
private:
mean(const mean & a) = default;
mean & operator=(const mean & a) = default;
};
template<typename Data, typename Result> std::ostream & operator<<(std::ostream & o , const mean<Data, Result> & a ){
a.print(o,' ');
return o;
}
template<typename Data, typename Result> std::istream & operator>>(std::istream & i , mean<Data, Result> & a ){
typename mean<Data,Result>::value_type temp;
i>>temp;
a.add_data(temp);
return i;
}
template<typename Data, typename Result, typename IncrOp, typename ResOp, int InitPar=0 >
class mean_impl final: public mean<Data, Result> {
public:
// in C++98 typedef Data data_type; typedef Result result_type;
using value_type=Data;
using result_type=Result;
using incrop_type=IncrOp;
using resop_type=ResOp;
mean_impl(): ncount_{}, rvalue_{static_cast<value_type>(InitPar)}, mean_{} {};
mean_impl & add_data(Data d) override {
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);
return *this;
}
result_type get_mean() const override { return mean_;}
void print(std::ostream &o=std::cout, const char term='\n') const override {
o << " Mean: " << get_mean() << term;
}
private:
IncrOp increment_;
ResOp result_;
Data ncount_;
Data rvalue_;
Result mean_;
};
#endif // CLASS_MEAN_TEMPLATE_H_
#include <iostream>
#include <vector>
#include "functors.h"
#include "mean_template.h"
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_impl<data_type,result_type,sum_type,divide_type>;
using geometrical_type=mean_impl<data_type,result_type,multiply_type,nroot_type,1>;
using mean_type=mean<data_type,result_type>;
using mean_container_type=std::vector<mean_type *>;
arithmetic_type a;
geometrical_type b;
mean_container_type c;
// Add mean into the container
c.push_back(new arithmetic_type{});
c.push_back(new geometrical_type{});
data_type indata{};
std::cout <<"Enter values [Ctrl-D to finish]: " <<std::endl;
while(std::cin>>indata){
a.add_data(indata);
b.add_data(indata);
for(auto & i: c) i->add_data(indata);
}
std::cout << " Arithmetic mean: " << a.get_mean() << "\n Geometrical mean: " << b.get_mean() << std::endl;
for(const auto & i: c) i->print();
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment