Listing 3: A better expression template

// Replaces EtMatrixAdd of Listing 2
template<
  typename T, size_t n, size_t m, 
  typename LeftOp, typename RightOp>
class EtMatrixAdd
{
public:
  EtMatrixAdd(const LeftOp& lhs, const RightOp& 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 LeftOp& m_lhs;
  const RightOp& m_rhs;
};

// Replaces operator= of Listing 2
template<
  typename T, size_t n, size_t m, 
  typename LeftOp, typename RightOp>
Matrix<T, n, m>& operator=(
  Matrix<T, n, m>& lhs, 
  const EtMatrixAdd<T, n, m, LeftOp, RightOp>& 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 operator+ of Listing 2
template<typename T, size_t n, size_t m>
inline EtMatrixAdd<T, n, m, Matrix<T, n, m>, Matrix<T, n, m> >
operator+(
  const Matrix<T, n, m>& lhs, 
  const Matrix<T, n, m>& rhs
  ) {
  return 
    EtMatrixAdd<T, n, m, Matrix<T, n, m>, Matrix<T, n, m> >(
      lhs, rhs
      );
}

// Second operator+
template<
  typename T, size_t n, size_t m, 
  typename LeftOp, typename RightOp
  >
inline EtMatrixAdd<
  T, n, m, 
  EtMatrixAdd<T, n, m, LeftOp, RightOp>, 
  Matrix<T, n, m> > 
operator+(
  const EtMatrixAdd<T, n, m, LeftOp, RightOp>& lhs, 
  const Matrix<T, n, m>& rhs
  ) {
  return 
    EtMatrixAdd<T, n, m, 
      EtMatrixAdd<T, n, m, LeftOp, RightOp>, 
      Matrix<T, n, m> >(lhs, rhs);
}