Using templates sometimes cause exponential grow of the code instantiated. This situation is sometime called codeblow. Let us to analize the problem, and see, how to avoid codeblow.
#ifndef MATRIX_H #define MATRIX_H #include <string> template <class T> class matrix { public: struct matrixError { matrixError( std::string r) : reason(r) { } const std::string reason; }; struct indexError : public matrixError { indexError( int i, int j) : matrixError("Bad index"),row(i), col(j) { } int row; int col; }; matrix( int i, int j ); matrix( const matrix &other); ~matrix(); matrix operator=( const matrix &other); int rows() const { return x; } int cols() const { return y; } T& at( int i, int j) throw(indexError); T at( int i, int j) const throw(indexError); T& operator()( int i, int j); T operator()( int i, int j) const; matrix operator+=( const matrix &other); private: int x; int y; T *v; void copy( const matrix &other); void check( int i, int j) const throw(indexError); }; $ ls -l a.out 19722
A generally good technique to cut off the type-independent part of the class from those dependent from the parameter. Inheritance here is a good solution:
#ifndef MATRIX_H #define MATRIX_H #include <string> class matrixBase { public: struct matrixError { matrixError( std::string r) : reason(r) { } const std::string reason; }; struct indexError : public matrixError { indexError( int i, int j) : matrixError("Bad index"),row(i), col(j) { } int row; int col; }; matrixBase( int i, int j) : x(i), y(j) { } int rows() const { return x; } int cols() const { return y; } protected: int x; int y; void check( int i, int j) const throw( indexError ) { if ( ( 0 <= i && i < x ) && ( 0 <= j && j < y ) ) /* ok */ ; else throw indexError(i,j); } }; template <class T> class matrix : public matrixBase { public: matrix( int i, int j ); matrix( const matrix &other); ~matrix(); matrix operator=( const matrix &other); T& at( int i, int j) throw(indexError); T at( int i, int j) const throw(indexError); T& operator()( int i, int j); T operator()( int i, int j) const; matrix operator+=( const matrix &other); private: T *v; void copy( const matrix &other); }; $ ls -l 16851