1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
|
#include<iostream>
#include<functional>
#include<vector>
// message to print during evaluation, in order to track the evaluation path.
#define msg std::cout<<typeid(*this).name()<<std::endl
class Expression{
public:
std::function<double(void)> evaluate;
template<typename T>
Expression(const T &RH){evaluate = RH.evaluate;}
template<typename T>
Expression& operator=(const T &RH)
{evaluate = RH.evaluate; return *this;}
};
class Number{
double val;
public:
Number()=default;
std::function<double()> evaluate;
Number(const double &x):val(x)
{evaluate = [this](){msg; return this->val;}; }
Number(const Number &x):val(x.evaluate())
{evaluate = [this](){msg; return this->val;}; }
};
template<typename leftHand,typename rightHand>
class Addition{
const leftHand &LH;
const rightHand &RH;
public:
std::function<double()> evaluate;
Addition(const leftHand &LH, const rightHand &RH):LH(LH),RH(RH){
evaluate = [this]()
{msg; return this->LH.evaluate() + this->RH.evaluate();};
}
};
template<typename leftHand,typename rightHand>
auto operator+(const leftHand &LH, const rightHand &RH)
{return Addition<leftHand,rightHand>(LH,RH); }
using std::cout;
using std::endl;
inline Expression func (std::vector<Expression> x, int i){
cout<<i<<endl;
if (i==0){return static_cast<Expression>(x[0]);}
return static_cast<Expression>( x[i] + func(x,i-1) ) ;
};
int main(){
Number y(-2.);
Number x(1.33);
Expression z(y+x);
Expression w(x+y+x);
// works
z =x;
cout<<z.evaluate()<<endl;
cout<<(z+z+z+z).evaluate()<<endl;
// Segfault due to recusion
// z =z+x;
// cout<<z.evaluate()<<endl;
// Unkown Segfault
// z = x+y ;
// cout<<(z+z).evaluate()<<endl;
// cout<<typeid(z+z).name()<<endl;
// Unkown Segfault
// z = w+y+x+x;
// cout<<z.evaluate()<<endl;
// Unkown Segfault
// std::vector<Expression> X={x,y,x,y,x,y,x,y};
// cout << typeid(func(X,X.size()-1)).name() << endl;
// cout << (func(X,X.size()-1)).evaluate() << endl;
return 0;
}
| |