Hello all,

I tried to use expression templates to perform arithmetic operations on matrices of complex numbers. Since I am just learning expression templates, I thought I'll write my own templates for both arrays and complex numbers. The files main.cpp and Complex.h and Matrix.h are attached.

The above three lines of code are the ones I have a query about. m1 and m2 are matrices of complex numbers whose real and imaginary parts are floats.Code:cout << "\n" << "expression ((m1 * m2) + (m1 * m2))" << endl; ((m1 * m2) + (m1 * m2)); cout << "\n" << "expression ((m1 * m2) + (m1 * m2)): display with .show() function" << endl; ((m1 * m2) + (m1 * m2)).show(); cout << "\n" << "expression ((m1 * m2) + (m1 * m2)): access one element with operator()" << endl; cout << ((m1 * m2) + (m1 * m2))(0,0) << endl;

I need to interpret the results of these lines of code. The first line gives me this:

This code does not perform any function in terms of computation or output of values. So my question is: Does this only create an expression tree?expression ((m1 * m2) + (m1 * m2))

Constructor Mat_dotProduct(ExprTLeft& x, ExprTRight& y) called

Constructor Mat_dotProduct(ExprTLeft& x, ExprTRight& y) called

Constructor Mat_add(ExprTLeft& x, ExprTRight& y) called

Destructor ~Mat_add() called

Destructor ~Mat_dotProduct() called

Destructor ~Mat_dotProduct() called

This brings us to the next question regarding the second line of code that gives this output:

Here the values of the final array are sent to the screen. However, every time an element of the expression tree is accessed/parsed/executed (or other please tell me the correct word), a copy constructor is called.expression ((m1 * m2) + (m1 * m2)): display with .show() function

Constructor Mat_dotProduct(ExprTLeft& x, ExprTRight& y) called

Constructor Mat_dotProduct(ExprTLeft& x, ExprTRight& y) called

Constructor Mat_add(ExprTLeft& x, ExprTRight& y) called

Complex() constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex() constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

(20.0224, 27.1327)

Complex() constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex() constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

(4.56637, 29.1327)

Complex() constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex() constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

(27.164, 37.3056)

Complex() constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex() constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

(11.708, 39.3056)

Expression has 2 rows and 2 columns

Destructor ~Mat_add() called

Destructor ~Mat_dotProduct() called

Destructor ~Mat_dotProduct() called

The third line of code that accesses only one element of the expression gives this:

Again all these copy constructors for acessing one element?expression ((m1 * m2) + (m1 * m2)): access one element with operator()

Constructor Mat_dotProduct(ExprTLeft& x, ExprTRight& y) called

Constructor Mat_dotProduct(ExprTLeft& x, ExprTRight& y) called

Constructor Mat_add(ExprTLeft& x, ExprTRight& y) called

Complex() constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex() constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

Complex(const Complex &cmplx) copy constructor is called

(20.0224, 27.1327)

Destructor ~Mat_add() called

Destructor ~Mat_dotProduct() called

Destructor ~Mat_dotProduct() called

If the goal of expression templates is to reduce the number of temporary objects being created, it is a little surprising to see so many copy constructors when trying to use this concept. Is it that expression templates are used with arrays here instead of scalars and so the benefit is lost?

Can anyone point me to something I might be missing?

Thank you in advance