I am trying to understand an aspect of expression templates.
Let's say we are applying the technique to matrices.
Suppose we have three concrete matrices a,b,c
of type Matrix<double, ConcreteMatrix<double>>
. Here the class Matrix<double, T>
is just a shell that contains a member of type T
. The ConcreteMatrix<double>
is the actual matrix class.
In expression templates operator+()
applied to two objects a + b
, returns an object of type Matrix<double, Sum<type(a),type(b)>>
, where I wrote type(a)
and type(b)
to not make the code shorter and easier to read.
Inside, the class Sum<T,S>
stores two ** constant references** to the objects a
and b
.
My question arises when computing (a + b) + c
. Well, to be more precise computing Matrix<double, ConcreteMatrix<double>> d = (a + b) + c
. Let me recall here that it is operator=
the one that takes care of actually doing the computation and filling up d
with the results.
We have that operator+(a, b)
returned that Matrix
which is really a Sum
inside. This object is temporary, if I understand it correctly. Let's call it pab
. Now it is the time to execute operator+(pad, c)
This one returns an object of type Matrix<double,Sum<type(pad),type(c)>>
, which contains constant references to pab
and to c
. Let's call this object ppabc
.
I understand how pab was 'alive' in the scope of the body of operator+(pad,c)
. So, it is okay to create ppabc
containing a reference to pab
.
Question: But what happens when we go outside operator+(pad, c)
? Isn't pab
supposed to 'die' when we go outside operator+(pad, c)
? This doesn't seem to be the case. Why? (I have a executed the implementation as written in Todd Veldhuizen and David Vandevoorde's book and it works fine.) That means that somehow the temporary pab
still lives outside the body of operator+(pad, c)
and the object that this operator returns can still access its reference to pab
and ask for the values it contains.
I want to understand exactly what is the underlying reason why this temporary lives beyond the scope I would have imagined because I want to apply the technique of expression templates to get lazy evaluation for other functions, say exp()
. I ran into troubles (execution errors due to a temporary getting destroyed). The errors disappeared when instead of a reference I stored a concrete object inside Matrix<double, Exponential<type(a)>>
. So understanding the questions above would help.