Bonjour à tous.

Je suis en train de m'amuser à construire quelques expressions templates en me basant sur l'article http://www.angelikalanger.com/Articl...nTemplates.htm

avec quelques ajouts de C++11.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
 
#include <iostream> 
 
template <typename T> 
class Expression 
{ 
    const T& expr; 
public: 
    Expression(const T& t2):expr(t2){} 
    typename T::result operator()() 
    { 
        std::cout<<"expr eval"<<std::endl;     
        expr(); 
    } 
}; 
 
template <class T> Expression<T> makeExpression(const T& t) 
{ 
    std::cout<<"make expr"<<std::endl; 
    return Expression<T>(t); 
} 
 
template <class T> class Var 
{ 
    T t; 
public : 
    Var(const Var& o):t(o.t){std::cout<<"copy"<<std::endl;} 
    Var(T t2):t(t2){std::cout<<"value "<<t<<std::endl;} 
    Var():t(T()){} 
    Var(Var&& o):t(std::move(o.t)){std::cout<<"move"<<std::endl;} 
    T operator()() const 
    { 
        return t; 
    } 
 
    Var& operator=(T o) 
    { 
        t=o; 
        return *this; 
    } 
    ~Var(){std::cout<<"dst"<<std::endl;} 
    typedef T result; 
}; 
 
template <typename T,typename U,typename Op> class ExpressionBin 
{ 
    const T& t; 
    const U& u; 
    Op op; 
public: 
    ExpressionBin(){std::cout<<"wtf"<<std::endl;} // <<LA 
 
    ExpressionBin(const T& tt,const U& uu): 
    t(tt), 
    u(uu),op(Op()) 
    { 
 
    } 
 
    typedef decltype(op(T(),U())) result; 
    result operator()() const 
    { 
        return op(t,u); 
    } 
}; 
 
#define helperEval(op)     template <class T, class U>  \ 
    decltype((typename T::result() op  typename U::result())) \ 
    operator()(const T& t,const U& u) const \ 
    { \ 
        std::cout<<#op " called " \ 
        <<t()<<" "<<u()<<std::endl;    \ 
        return t() op u(); \ 
    } 
 
struct plus 
{ 
    helperEval(+) 
}; 
 
struct mul 
{ 
     helperEval(*) 
}; 
 
struct DIV 
{ 
     helperEval(/) 
}; 
 
struct moins 
{ 
     helperEval(-) 
}; 
 
 
template <class T, class U> ExpressionBin<T,U,plus> 
 operator+(const T& t,const U& u) 
{ 
    return ExpressionBin<T,U,plus>(t,u); 
} 
template <class T, class U> ExpressionBin<T,U,mul> 
operator*(const T& t,const U& u) 
{ 
    return ExpressionBin<T,U,mul>(t,u); 
} 
 
template <class T, class U> ExpressionBin<T,U,DIV> 
operator/(const T& t,const U& u) 
{ 
    return ExpressionBin<T,U,DIV>(t,u); 
} 
 
template <class T, class U> ExpressionBin<T,U,moins> 
operator-(const T& t,const U& u) 
{ 
    return ExpressionBin<T,U,moins>(t,u); 
} 
 
int main(int argc, char *argv[]) 
{ 
    Var<int> x(5); 
    const Var<int> y(3); 
    const Var<double> z(+2.5); 
    Var<double> a; 
    Var<int> b=2; 
    auto e= makeExpression(x*y+z); 
    std::cout<<"========="<<std::endl; 
    a=0.5; 
    std::cout<<"=>"<<e()<<std::endl; 
    std::cout<<"========="<<std::endl; 
    return 0; 
}
Pour le moment le code marche (disons qu'il me donne le résultat attendu) mais j'ai une incompréhension

Si je commente le constructeur par défaut de ExpressionBin, le code ne veut plus compiler car il ne trouve pas le dit constructeur. Jusque là c'est logique ....

Sauf que ce soucis apparaît seulement quand j'ai plus d'une opération dans mon calcul. si je fais seulement x*y, pas besoin constructeur par défaut. Mais dès que je passe à x*y+z (ou quoi que ce soit d'autre), j'en ai besoin.

Ce qui me choque, c'est que le constructeur n'est jamais appelé et que les références puissent être laissées non initialisées !! D'ailleurs, si je le remplace par ExpressionBin()=default;
ca plante !!

Est ce que quelqu'un aurait une explication à ce phénomène ?

Merci beaucoup !
David.