# Expression Templates

By Thomas Becker, June 01, 2003

This is the second in a short series of articles on the subject of using C++ template and template metaprogramming techniques to create highly efficient code that makes C++ acceptable for scientific and numerical programming. In my last column, I talked about loop unrolling via inline function templates. I also mentioned a much more difficult problem, namely, the elimination of gratuitous temporary objects and gratuitous loop iterations when overloading operators such as `operator+`

for algebraic objects such as matrices. Expression templates solve that problem. Todd Veldhuizen and David Vandevoorde independently invented expression templates. Todd Veldhuizen's original article from the now defunct *C++ Report* is reprinted in *C++ Gems* [1]. David Vandevoorde's take on expression templates can be found in the book on C++ templates he wrote with Nicolai Josuttis [2]. This book is highly recommended reading even if you're not all that interested in advanced topics such as expression templates. It is clearly the definitive source and reference for all your template-related questions.
** Listing 1:** A very simple Matrix class

template<typename T, size_t n, size_t m>
class Matrix
{
public:
Matrix(){}
Matrix(const Matrix& rhs) {
for(int i=0; i<n; ++i)
for(int j=0; j<m; ++j)
ElementAt(i,j) = rhs.ElementAt(i,j);
}
Matrix& operator=(const Matrix& rhs) {
if( this != &rhs )
for(int i=0; i<n; ++i)
for(int j=0; j<m; ++j)
ElementAt(i,j) = rhs.ElementAt(i,j);
return *this;
}
virtual ~Matrix() {}
const T& ElementAt(size_t n, size_t m) const
{ return arrData[n][m]; }
T& ElementAt(size_t n, size_t m)
{ return arrData[n][m]; }
private:
// C-style array for efficiency and locality of reference
T arrData[n][m];
};
template<typename T, size_t n, size_t m>
Matrix<T, n, m> operator+(
const Matrix<T, n, m>& lhs,
const Matrix<T, n, m>& rhs
) {
Matrix<T, n, m> matSum;
for(int i=0; i<n; ++i)
for(int j=0; j<m; ++j)
matSum.ElementAt(i,j) =
lhs.ElementAt(i,j) + rhs.ElementAt(i,j);
return matSum;
}