編輯: 請注意,我在這裏最終目的不是具有一流的工作,僅僅是學習更多有關模板:-)嵌套模板和構造
假設你有一個實現載體的模板類:
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;
}
因此,我將不再需要構造函數的參數,但是這也迫使我寫的是一個到處模板(由exmample笨拙的代碼,每個函數使用一個Vector
應被聲明爲
template <typename T, size_t N>
void foo (Vector<T,N> &vec) {...}
你有更好的辦法呢?
編輯:
作爲解決方案,我從Fooz先生和chubsdad的帖子中獲得靈感。這就是我解決問題的方法:
/* 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;
};
非常感謝大家!
爲什麼'foo'「笨拙」?即使沒有N參數,它仍然會被模板化。 – 2010-08-15 12:05:07
'size_t N'和運行時'dim'值解決了不同的問題。如果大小在編譯時是恆定的並且已知的,那麼你應該使用'size_t N'的方式,因爲它使用了類型檢查。然後在編譯時診斷可能的溢出。在這種情況下,根本不需要'new' - 只需放入一個普通的數組,像'boost :: array'。 –
2010-08-15 12:27:27
@jon hanson:是的,但是類型比值更普遍,因此定義了'foo',因此定義了'foo',它比'foo'更好(第 &vec);'。對於第二個,我傾向於將foo定義爲模板函數。 –
Dacav
2010-08-15 12:41:26