Hi everybody!
Edit: Note that my final purpose here is not having the class working, is just learning more about templates :-)
Suppose you have a template class which implements a vector:
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;
}
And suppose you want to build a matrix with it. A matrix is just a vector of vectors, thus it can be designed as follows:
template <typename T>
class Matrix : public Vector<Vector<T> >
{
/*...*/
}
And here comes trouble: In the constructor I need to provide rows and columns as parameter to the internal vectors. It should be something like
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 */
{
}
Obviously I cannot write Vector<Vector<T>(nrows)>(ncols)
, but that's what I would need!
A possible solution would be including size inside the template:
template <typename T, size_t N>
class Vector
{
public:
Vector() {
elements = new T[N];
}
/* Here more stuff, like operator[] etc... */
private:
T * elements;
}
Hence I would no longer need constructor parameters, but this also forces me to write clumsy code with templates everywhere (by exmample, every function using a Vector
should be declared as
template <typename T, size_t N>
void foo (Vector<T,N> &vec) {...}
Do you have better solutions?
EDIT:
As solution I took inspiration from Mr Fooz's and chubsdad's posts. That's how I fixed the problem:
/* 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;
};
Thanks a lot to everyone!