Spa*_*rky 5 c++ templates policy-based-design
我想对模板类使用部分特化,以便该模板类的所有子节点都将使用该特化.让我用一个例子来解释:)
template < typename T, unsigned int rows, unsigned int cols>
class BaseMatrix {...};
Run Code Online (Sandbox Code Playgroud)
这个类将有子项指定矩阵的结构,如稀疏,密集,对角线,..
template < typename T, unsigned int rows, unsigned int cols>
class DiagonalMatrix : public BaseMatrix<T,rows,cols>{..}
Run Code Online (Sandbox Code Playgroud)
然后这些类将再次生成指定存储的子节点:堆栈数组,向量,列表,队列,..
template < typename T, unsigned int rows, unsigned int cols>
class StackDiagonalMatrix : public DiagonalMatrix<T, rows, cols> {..}
Run Code Online (Sandbox Code Playgroud)
然后有一个类Matrix,它提供所有数学功能.这个模板类实现了operator +,operator-等......
template <typename T,
template<typename, unsigned, unsigned> class MatrixContainer,
unsigned Rows,
unsigned Cols>
class matrix;
Run Code Online (Sandbox Code Playgroud)
对于这最后一堂课,我想写下这样的专业:
template <typename T,unsigned Rows, unsigned Cols>
class matrix<T, BaseMatrix, Rows, Cols> {};
template <typename T,unsigned Rows, unsigned Cols>
class matrix<T, DiagonalMatrix, Rows, Cols> {};
Run Code Online (Sandbox Code Playgroud)
但是当我编写一个继承自DiagonalMatrix的StackDiagonalMatrix时,它找不到DiagonalMatrix的特化 - 它实际上根本找不到专门化.
error: aggregate ‘matrix<int, StackDenseMatrix, 3u, 2u> matrix’ has incomplete type and cannot be defined
Run Code Online (Sandbox Code Playgroud)
现在有这个问题的解决方案吗?你能为几个模板类的父类编写专门化吗?
非常感谢!
涉及的完整来源:
template <typename T, unsigned int rows, unsigned int cols>
class BaseMatrix {
protected:
BaseMatrix(){};
static const unsigned rowSize = rows;
static const unsigned colSize = cols;
};
template <typename T, unsigned int rows, unsigned int cols>
class DenseMatrix : public BaseMatrix<T, rows, cols> {
protected:
DenseMatrix(){};
};
template <typename T, unsigned int rows, unsigned int cols>
class StackDenseMatrix : public DenseMatrix<T, rows, cols> {
public:
typedef T value_type;
private:
value_type grid[rows][cols];
StackDenseMatrix();
};
template<typename value_type, unsigned int rows, unsigned int cols>
StackDenseMatrix<value_type, rows,cols>::StackDenseMatrix () {
for (unsigned int i = 0; i < this->rowSize; i++) {
for (unsigned int j = 0; j < this->colSize; j++) {
grid[i][j] = 0;
}
}
}
template <typename T, template<typename, unsigned, unsigned> class MatrixContainer ,unsigned Rows, unsigned Cols>
class matrix;
template <typename T,unsigned Rows, unsigned Cols>
class matrix<T,BaseMatrix, Rows, Cols> {
matrix(){};
};
int main () {
matrix<int, StackDenseMatrix, 3, 2> matrix;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
继承不适用于模板特化。当您调用时matrix<int,StackDenseMatrix,3,2> matrix;,它将选择 的通用模板matrix,因为第二个参数是StackDenseMatrix, not BaseMatrix。即使这些类通过继承相关,但没有任何区别,它们不是完全相同的类型,因此编译器不会选择matrix.
为了解决你的问题,我认为继承在这种情况下不会给你带来任何好处。在泛型编程中,更合适的工具是类型特征、策略和概念。在这种情况下,您应该能够应用一些类型特征来实现类似的目标。我喜欢使用的一个技巧是默认模板参数依赖于先前的模板参数,然后进行部分特化。例如如下:
enum MatrixStorage {
DenseMatrix,
SparseMatrix
};
enum MatrixStructure {
GeneralMatrix,
SquareMatrix,
DiagonalMatrix //, ...
};
template <typename T, unsigned Rows, unsigned Cols>
class StackDenseMatrix {
public:
typedef T value_type;
static const MatrixStorage Storage = DenseMatrix;
static const MatrixStructure Structure = GeneralMatrix;
//..
};
//General template with default arguments:
template <typename T,
template <typename, unsigned, unsigned> class MatrixContainer,
unsigned Rows, unsigned Cols,
MatrixStorage Storage = MatrixContainer<T,Rows,Cols>::Storage,
MatrixStructure Structure = MatrixContainer<T,Rows,Cols>::Structure>
class matrix;
//Specialization with given arguments:
template <typename T,
template <typename, unsigned, unsigned> class MatrixContainer,
unsigned Rows, unsigned Cols>
class matrix<T,MatrixContainer,Rows,Cols,DenseMatrix,GeneralMatrix> {
//implementation of matrix for when the container is dense and has general structure...
};
int main() {
matrix<int,StackDenseMatrix,3,2> M; //no extra arguments, and the right specialization will be selected based on the traits of StackDenseMatrix.
return 0;
};
Run Code Online (Sandbox Code Playgroud)
我有自己的矩阵库,它严重依赖于模板元编程和通用编程技术,类似于上面的示例,为不同类型的矩阵结构和存储提供矩阵运算的特殊实现,并且这种方式工作得很好。我曾经对不同的矩阵类型使用继承,但现在我转而仅依赖类型特征、概念、策略和 Sfinae 开关,这是一个更实用的解决方案。
| 归档时间: |
|
| 查看次数: |
541 次 |
| 最近记录: |