# 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 2:** An oversimplified expression template

template<typename T, size_t n, size_t m>
class Matrix;
template<typename T, size_t n, size_t m>
class EtMatrixAdd
{
public:
EtMatrixAdd(
const Matrix<T, n, m>& lhs,
const Matrix<T, n, m>& rhs) : m_lhs(lhs), m_rhs(rhs) {}
T ElementAt(size_t n, size_t m) const
{ return m_lhs.ElementAt(n, m) + m_rhs.ElementAt(n, m); }
private:
const Matrix<T, n, m>& m_lhs;
const Matrix<T, n, m>& m_rhs;
};
// In addition to operator= of Listing 1
template<typename T, size_t n, size_t m>
Matrix<T, n, m>& operator=(
Matrix<T, n, m>& lhs,
const EtMatrixAdd<T, n, m>& rhs) {
for(int i=0; i<n; ++i)
for(int j=0; j<m; ++j)
lhs.ElementAt(i,j) = rhs.ElementAt(i,j);
return lhs;
}
// Replaces the operator+ of Listing 1
template<typename T, size_t n, size_t m>
inline EtMatrixAdd<T, n, m> operator+(
const Matrix<T, n, m>& lhs,
const Matrix<T, n, m>& rhs)
{ return EtMatrixAdd<T, n, m>(lhs, rhs); }