我正在构建一个矩阵库,并尝试使用policy-based design。所以我的基类是提供存储方法和一些访问函数的类。我还有一个函数矩阵,它提供了数学函数。这很有效,但由于返回类型的原因,运算符*存在一个主要问题。我将用一些代码来解释它。
提供堆栈存储的基类:
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;然后我有我的矩阵类,它提供了数学功能:
template <typename MatrixContainer >
class matrix : public MatrixContainer {
public:
typedef MatrixContainer Mcontainer;
matrix<Mcontainer>& operator +(const matrix<Mcontainer>&);
matrix<Mcontainer>& operator *(const matrix<Mcontainer>&);operator+总是有效的,operator*只适用于方阵。所以我们仍然需要一个来处理所有的矩阵。这就是它出错的地方。我已经尝试了几种方法,但都不起作用。我寻找这样的东西,在c++0x的帮助下(使用c++0x不是必需的),你会注意到“?”:)
friend auto operator * (const matrix<T1>& matrix1, const matrix<T2>& matrix2)
-> decltype(matrix<???>);这个问题的一个例子
matrix<denseStackMatrix<int,3,2> > matrix1;
matrix<denseStackMatrix<int,2,4> > matrix2;
matrix<denseStackMatrix<int,3,4> > matrix3 = matrix1 * matrix2;在这里,它将抱怨类型,因为它不匹配两个参数类型中的任何一个。但是编译器需要知道编译时的类型,而我不知道如何提供它。
我知道设计还有其他选择,但我真的在为这个场景寻找解决方案。
谢谢!
发布于 2011-05-27 07:02:58
采用@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;
// ...
}
};编辑:正如您在评论中所说,您还可以使用它来创建一个不使用以行和列大小作为模板参数的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
}
};用法:
// 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;发布于 2011-05-27 06:52:02
如何将MatrixContainer更改为模板模板参数?
template <class T, int Rows, int Cols>
class DenseStackMatrix {
public:
typedef T value_type;
private:
value_type grid[Rows][Cols];
};
template <class T, int Rows, int Cols, template<class, int, int> class MatrixContainer>
class Matrix : public MatrixContainer<T, Rows, Cols> {
public:
template <int ResultCols>
Matrix<T, Rows, ResultCols, MatrixContainer> & operator*(const Matrix<T, Cols, ResultCols, MatrixContainer> &);
};
int main() {
Matrix<int, 3, 2, DenseStackMatrix> matrix1;
Matrix<int, 2, 4, DenseStackMatrix> matrix2;
Matrix<int, 3, 4, DenseStackMatrix> matrix3 = matrix1 * matrix2;
}这样,您不仅可以进行编译时维度检查,还可以对其进行扩展,以允许不同容器类型的矩阵之间的乘法。
发布于 2011-05-27 08:52:27
只是因为我在这里找到所有的答案之前就做过了:
template <typename T, unsigned int M, unsigned int N>
struct Matrix
{
};
template <typename T, unsigned int M, unsigned int MN, unsigned int N>
Matrix<T, M, N> operator*(Matrix<T, M, MN> const & lhs, Matrix<T, MN, N> const & rhs)
{
return Matrix<T, M, N>();
}
int main()
{
Matrix<int, 3, 4> prod = Matrix<int, 3, 2>() * Matrix<int, 2, 4>();
// Fails to compile as desired
// g++ gives:
//matrix.cpp: In function 'int main()':
//matrix.cpp:20: error: no match for 'operator*' in 'Matrix<int, 3u, 2u>() * Matrix<int, 3u, 4u>()'
Matrix<int, 3, 4> prod1 = Matrix<int, 3, 2>() * Matrix<int, 3, 4>();
}此解决方案可能不适合您的设计模式,但使用operator*的自由函数实现来推断(和检查)模板参数,如果不满足矩阵乘法的约束,则会导致编译时错误。
https://stackoverflow.com/questions/6145247
复制相似问题