C++ 11模板,确定返回类型

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)

这里它会抱怨类型,因为它与两种参数类型中的任何一种都不匹配.但编译器需要在编译时知道类型,我不知道如何提供它.

我知道设计还有其他选择,但我真的在寻找这种情况的解决方案..

谢谢 !

Xeo*_*Xeo 5

汲取@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)