Редактировать : обратите внимание, что моя последняя цель - не работать с классом, а просто узнать больше о шаблонах: -)
Предположим, у вас есть шаблонный класс, который реализует вектор:
template <typename T>
class Vector
{
public:
Vector(size_t dim) {
dimension = dim;
elements = new T[dim];
}
/* Here more stuff, like operator[] etc... */
private:
size_t dimension;
T * elements;
}
И предположим, что вы хотите построить матрицу из нее.Матрица - это просто вектор векторов, поэтому ее можно сконструировать следующим образом:
template <typename T>
class Matrix : public Vector<Vector<T> >
{
/*...*/
}
И тут возникает проблема: в конструкторе мне нужно предоставить строки и столбцы в качестве параметра для внутренних векторов.Это должно быть что-то вроде
template <typename T>
Matrix<T>::Matrix (size_t ncols, size_t nrows)
: Vector<Vector<T> > /* Here I need to specify size for both
* internal and external vectors */
{
}
Очевидно, я не могу написать Vector<Vector<T>(nrows)>(ncols)
, но это то, что мне нужно!
Возможное решение будет включать в себя размер внутри шаблона:
template <typename T, size_t N>
class Vector
{
public:
Vector() {
elements = new T[N];
}
/* Here more stuff, like operator[] etc... */
private:
T * elements;
}
Следовательно, мне больше не нужны параметры конструктора, но это также вынуждает меня писать неуклюжий код с шаблонами везде (например, каждая функция, использующая Vector
, должна быть объявлена как
template <typename T, size_t N>
void foo (Vector<T,N> &vec) {...}
Есть ли у вас лучшие решения?
РЕДАКТИРОВАТЬ:
В качестве решения я черпал вдохновение из сообщений мистера Фуза и Чубсдада. Вот как я решил проблему:
/* The RowAccess class is just an array wrapper which raises an exception
* if you go out of bounds */
template <typename T>
class RowAccess
{
public:
RowAccess (T * values, unsigned cols) : values(vals), cols(c) {}
T & operator[] (unsigned i) throw (MatrixError) {
if (i < cols) return values[i];
else throw MatrixError("Column out of bound");
}
private:
T * values;
unsigned cols;
};
template <typename T>
class Matrix
{
public:
Matrix (unsigned rows, unsigned cols) {...}
virtual ~Matrix () {...}
RowAccess<T> operator[] (unsigned row) {
if (row < rows) return RowAccess<T>(values + cols * row, cols);
else throw MatrixError("Row out of boundary");
}
private:
unsigned rows;
unsigned cols;
T * values;
};
Большое спасибо всем!