Copy member function of expression template

I am trying to write a library using expression templates, and I need to find a way to copy the expression in an variable without evaluating it (for example I want to copy different members, including member functions). Also, since I want to do this for different types of expressions, I need some kind of type erasure.

I tried to do this in a simple example, using lambdas as members, but I often get Segfault.

In the code below, I have defined Number and Addition class, as the basis for what I am trying to do. Also, I define an Expression class that allows me to use Expression variables to store combinations of Number and Addition expressions.



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;
}


Basically I want to be able to do the following

1
2
3
4
5
6
7
Number x(5.),y(3.);
Expression z;

z=x;
z=z+y;

z.evaluate();


Is there any way to do this either directly, or using some recursive function as in the code above?
Last edited on
Topic archived. No new replies allowed.