Шаблоны классов наследников и вложенные типы.
От: Razard Россия  
Дата: 24.05.15 11:31
Оценка:
Есть базовый шаблонный класс матриц MatrixBase и несколько шаблонных наследников MatrixDense, MatrixSparse и т.д.:

template <int _rows, int _cols, typename type> class MatrixBase
{
public:
    type* _pData;
    int _r;
    int _c;

    void _reset(void)
    {
        _pData = 0;
        _r = 0;
        _c = 0;
    }

    void _flush(void)
    {
        try { delete[] _pData; } catch(...) {};
    }

    bool _alloc(int rows, int cols)
    {
        if (rows*cols==0) return false;
        try
        {
            _pData = new type[rows*cols];
        }
        catch(...)
        {
            return false;
        }
        _r = rows;
        _c = cols;
        return true;
    }

    MatrixBase(void)
    {
        _reset();
    }

    ~MatrixBase(void)
    {
        _flush();
        _reset();
    }

    const type& _get(int r, int c) const
    {
        return _pData[_c*r+c];
    }

    type& _get(int r, int c)
    {
        return _pData[_c*r+c];
    }

    template <typename t>
    void _set(int r, int c, const t& val)
    {
        _pData[_c*r+c] = val;
    }

    template <int _rowsM, int _colsM>
    void set(const MatrixBase<_rowsM,_colsM,type>& M)
    {
        for (int r = 0; r<_r; r++)
            for (int c = 0; c<_c; c++)
                _set(r,c, M._get(r,c));
    }

    template <int _rowsM, int _colsM>
    void operator=(const MatrixBase<_rowsM,_colsM,type>& M)
    {
        set(M);
    }

};

template <int _rows, int _cols, typename type> class MatrixDense : public MatrixBase<_rows,_cols,type>
{
public:
    MatrixDense(void) { _alloc(_rows, _cols); }
    MatrixDense(int rows, int cols) { _alloc(rows, cols); }
    ~MatrixDense(void) {}
};

template <int _rows, int _cols, typename type> class MatrixSparse : public MatrixBase<_rows,_cols,type>
{
public:
    MatrixSparse(void) { _alloc(_rows, _cols); }
    MatrixSparse(int rows, int cols) { _alloc(rows, cols); }
    ~MatrixSparse(void){}
};


В простых случаях все работает:
MatrixDense<3,3,float> D;
MatrixSparse<3,3,float> S;
D.set(S);


В более сложном случае с одинаковыми типами элементам-матрицами тоже все работает:
MatrixDense<0,0,MatrixDense<3,3,float>> D(4,4);
MatrixSparse<0,0,MatrixDense<3,3,float>> S(4,4);
D.set(S);


Однако, если типы элементов-матриц различны — не собирается:
MatrixDense<0,0,MatrixDense<3,3,float>> D(4,4);
MatrixDense<0,0,MatrixSparse<3,3,float>> S(4,4);
D.set(S);


Пишет:

Error: no instance of function template "MatrixDense<_rows,_cols,type>::set [with _rows=0, _cols=0, type=MatrixDense<3,3,float> ]" matched the argument list
argument types are: (MatrixDense<0,0,MatrixSparse<3,3,float>>)
object type is: MatrixDense<0,0,MatrixDense<3,3,float>>


Понятно, что конечные типы по факту различны, но они наследуются от общего предка, и как в первом случае все работает. Почему в последнем не работает?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.