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;
}