   Advanced Template Question
  While trying to write a matrix class I stumbled upon the following problem. I started by constructing a basic matrix template:template< int rows, int cols, class ScalarType, template< int, int, typename > class StoragePolicy >class Matrix : public StoragePolicy< rows, cols, ScalarType > {// ..};And then I created the most basic type of storage policy:template< int rows, int cols, class ScalarType >class DenseStorage {public:ScalarType & Get( int row, int col ) {return data[ row * cols + col ];}private:ScalarType data[ rows * cols ];};But the whole reason I separated the storage into a policy was so I could have a storage policy that is a submatrix of another matrix:template< int rows, int cols, class ScalarType, template< int, int, typename > class StoragePolicy >class SubMatrix {public:SubMatrix( Matrix< rows, cols, ScalarType, StoragePolicy > & _matrix, int _startrow, int _startcol ) : matrix( _matrix ), startrow( _startrow ), startcol( _startcol ) { }ScalarType & Get( int row, int col ) {return matrix.Get( startrow + row, startcol + col );}private:Matrix< rows, cols, ScalarType, StoragePolicy > & matrix;int startrow, int startcol;};The problem here is that the template arguments don't match because of the extra 'template< int, int, typename > class Storage' on the SubMatrix class. Now the obvious solution here is just to take off 'template< int, int, typename >' on the original matrix definition, but this tends to make declaring a matrix very verbose, i.e. 'Matrix< 3, 3, float, DenseStorage< 3, 3, float > >' rather than 'Matrix< 3, 3, float, DenseStorage >'. So, that said, does anyone know a way around this?   
  I know no way around it, but don't you think the added flexibility might be worth it?   ;  Possibly.. but then you run into issues where Matrix dimensions don't match, i.e. Matrix< 1, 2, float, DenseStorage< 3, 4, float > >, there's no compile time protection for this mistake   ;  You made an error while defining startcol.    template< int rows,    int cols,    class ScalarType,    template< int, int, typename > class StoragePolicy >    class SubMatrix {   ...    private:   Matrix< rows, cols, ScalarType, StoragePolicy > & matrix;   int startrow; //or int startrow, startcol;   int startcol;    }; [Edited by - johnstanp on May 12, 2009 2:55:46 AM];  I think I don't fully understand your intention, as what you posted (small addition from my side) ...template< int rows,int cols,class ScalarType,template< int, int, typename > class StoragePolicy >class Matrix : public StoragePolicy< rows, cols, ScalarType > {// ..};template< int rows,int cols,class ScalarType >class DenseStorage {public:ScalarType & Get( int row, int col ) {return data[ row * cols + col ];}private:ScalarType data[ rows * cols ];};template< int rows,int cols,class ScalarType,template< int, int, typename > class StoragePolicy >class SubMatrix {public:   SubMatrix(Matrix< rows, cols, ScalarType, StoragePolicy > &parent) : matrix(parent) {}SubMatrix( Matrix< rows, cols, ScalarType, StoragePolicy > & _matrix, int _startrow, int _startcol ) :matrix( _matrix ), startrow( _startrow ), startcol( _startcol ) { }ScalarType & Get( int row, int col ) {return matrix.Get( startrow + row, startcol + col );}private:Matrix< rows, cols, ScalarType, StoragePolicy > & matrix;int startrow, startcol;};... works perfectly fine for this example (g++):int main () {   Matrix<3,3,float,DenseStorage> mm;   SubMatrix<3,3,float,DenseStorage> sm (mm);}Maybe you can elaborate more on top of the example I posted.   ;Quote:Original post by MilfredCubicleXPossibly.. but then you run into issues where Matrix dimensions don't match, i.e. Matrix< 1, 2, float, DenseStorage< 3, 4, float > >, there's no compile time protection for this mistakeThis could be asserted at compile time like so : #include <boost/static_assert.hpp>template <int r, int c, typename T>struct ExampleStoragePolicy{static const int rows = r;static const int cols = c;};template <int r, int c, typename T, typename StoragePolicy>struct Matrix{BOOST_STATIC_ASSERT((r == StoragePolicy::rows) && (c == StoragePolicy::cols));};// errorMatrix<1, 2, float, ExampleStoragePolicy<3, 4, float> > myMatrix;// no errorMatrix<3, 4, float, ExampleStoragePolicy<3, 4, float> > myMatrix;It means that the storage has to have the rows and columns members, but it's not like anyone could forget to do it, it will cause a compile error anyway if they aren't there.   ;Quote:Original post by phresnelMaybe you can elaborate more on top of the example I pQuote:Original post by MilfredCubicleXBut the whole reason I separated the storage into a policy was so I could have a storage policy that is a submatrix of another matrix:He wants to be able to use SubMatrix as a storage policy for another Matrix.   ;  You can create a template class inside SubMatrix called Policy and define policy related stuff there and when you initialize the matrix you write: Matrix< ... , SubMatrix<AnotherPolicy>::Policy>Hope this helped,RaxvanEdit:something like:template<template< int, int, typename > class StoragePolicy >   int rows=0, // this is not needed if you use the subMatrix only as a //policyint cols=0, class ScalarType=int, class SubMatrix {public://...  template < int r,int c,typename w>  class Policy {  .....  }private:};;Quote:Original post by MakaanYou can create a template class inside SubMatrix called Policy and define policy related stuff there and when you initialize the matrix you write: Matrix< ... , SubMatrix<AnotherPolicy>::Policy>Hope this helped,RaxvanEdit:something like:*** Source Snippet Removed ***Exactly what I was looking for, thanks   