Spa*_*rky 14 c++ templates design-patterns policy-based-design c++11
我正在构建一个矩阵库,我正在尝试使用基于策略的设计.所以我的基类是提供存储方法和一些访问功能的类.我还有一个提供数学函数的函数矩阵.这很好用,但由于返回类型,运算符*存在一个主要问题.我将用一些代码解释它.
提供堆栈存储的基类:
template < typename T, unsigned int rows, unsigned int cols>
class denseStackMatrix {
public:
typedef T value_type;
private:
value_type grid[rows][cols];
const unsigned int rowSize;
const unsigned int colSize;
Run Code Online (Sandbox Code Playgroud)
然后我有我的矩阵类,它提供了数学功能:
template <typename MatrixContainer >
class matrix : public MatrixContainer {
public:
typedef MatrixContainer Mcontainer;
matrix<Mcontainer>& operator +(const matrix<Mcontainer>&);
matrix<Mcontainer>& operator *(const matrix<Mcontainer>&);
Run Code Online (Sandbox Code Playgroud)
operator+总是有效,operator*只适用于方阵.所以我们仍然需要一个所有矩阵.这就是它出错了.我已经尝试了很少的东西,但没有尝试.我寻找这样的东西,在c ++ 0x的帮助下(c ++ 0x的使用不是必需的)你应该注意到"???" :)
friend auto operator * (const matrix<T1>& matrix1, const matrix<T2>& matrix2)
-> decltype(matrix<???>);
Run Code Online (Sandbox Code Playgroud)
问题的一个例子
matrix<denseStackMatrix<int,3,2> > matrix1;
matrix<denseStackMatrix<int,2,4> > matrix2;
matrix<denseStackMatrix<int,3,4> > matrix3 = matrix1 * matrix2;
Run Code Online (Sandbox Code Playgroud)
这里它会抱怨类型,因为它与两种参数类型中的任何一种都不匹配.但编译器需要在编译时知道类型,我不知道如何提供它.
我知道设计还有其他选择,但我真的在寻找这种情况的解决方案..
谢谢 !
汲取@hammar的想法,但部分专业化允许正常的语法,如问题所示:
template<class MatrixContainer>
class matrix;
template<
template<class,int,int> class MatrixContainer,
class T, int rows, int cols
>
class matrix< MatrixContainer<T,rows,cols> >{
typedef MatrixContainer<T,rows,cols> Mcontainer;
typedef matrix<Mcontainer> this_type;
static int const MyRows = rows;
static int const MyCols = cols;
public:
template<int OtherCols>
matrix<MatrixContainer<T,MyRows,OtherColls> > operator*(matrix<MatrixContainer<T,MyCols,OtherCols> > const& other){
typedef matrix<MatrixContainer<T,MyCols,OtherCols> > other_type;
typedef matrix<MatrixContainer<T,MyRows,OtherCols> > result_type;
// ...
}
};
Run Code Online (Sandbox Code Playgroud)
编辑:正如您在评论中所说,您也可以使用它来创建一个矩阵,该矩阵不使用具有行和列大小作为模板参数的MatrixContainer:
template<
template<class> class MatrixContainer,
class T
>
class matrix< MatrixContainer<T> >{
typedef MatrixContainer<T> Mcontainer;
typedef matrix<Mcontainer> this_type;
public:
// normal matrix multiplication, return type is not a problem
this_type operator*(this_type const& other){
// ensure correct row and column sizes, e.g. with assert
}
// multiply dynamic matrix with stack-based one:
template<
template<class,int,int> class OtherContainer,
int Rows, int Cols
>
this_type operator*(matrix<OtherContainer<T,Rows,Cols> > const& other){
// ensure correct row and column sizes, e.g. with assert
}
};
Run Code Online (Sandbox Code Playgroud)
用法:
// stack-based example
matrix<DenseStackMatrix<int,3,2> > m1;
matrix<DenseStackMatrix<int,2,4> > m2;
matrix<DenseStackMatrix<int,3,4> > m3 = m1 * m2;
// heap-based example
matrix<DenseHeapMatrix<int> > m1(3,2);
matrix<DenseHeapMatrix<int> > m2(2,4);
matrix<DenseHeapMatrix<int> > m3 = m1 * m2;
Run Code Online (Sandbox Code Playgroud)