【发布时间】:2020-12-09 12:36:47
【问题描述】:
我有一个模板矩阵类,其中包含一些典型的成员函数,例如inverse、determinant、operator* 等。我想在两个模板实现中重用这些成员函数的代码 固定-和动态尺寸矩阵。
这可能吗?如果是,如何?
在下面的代码中,与 Eigen 一样,我使用“-1”作为动态尺寸。是的,我知道我可以为此使用库,但对于我的应用程序,这是不可行的。 由于应用程序 (CUDA) 的性质,无法使用标准功能
是否可以根据模板参数制作不同成员变量大小的模板类? 比如Dynamic_Rows = -1和Dynamic_Cols = -1,那么数据就是T **data,但是否则为T data[Rows][Cols]。
到目前为止,我有一个用于动态大小矩阵的模板类(下面的“minimal”示例,请注意代码可能会出现错误/错误,因为我对“高级”类比较陌生模板)。
但是在固定大小的矩阵实例化的情况下,我希望有一个固定大小的数据成员变量。
template<class T, int Dynamic_Rows, int Dynamic_Cols>
class CMatrix<T, -1, -1>
{
private:
size_t n_rows, n_cols;
T** data;
void allocate_data();
void deallocate_data();
public:
CMatrix(const size_t n_rows, const size_t n_cols);
CMatrix(const CMatrix& other);
~CMatrix();
CMatrix& operator=(const CMatrix& rhs);
CMatrix exp() const;
};
例如下面exp()函数的代码
template <class T, int Dynamic_Rows, int Dynamic_Cols>
CMatrix<T, -1, -1> CMatrix<T, -1, -1>::exp() const
{
CMatrix<T, -1, -1> result(n_rows, n_cols);
for (size_t i = 0; i < n_rows; i++)
{
for (size_t j = 0; j < n_cols; j++)
{
result.data[i][j] = exp(result.data[i][j]);
}
}
return result;
}
我现在唯一能想到的同时允许动态和固定大小的矩阵是基本上实现该类的另一个模板
template<class T, size_t Rows, size_t Cols>
class CMatrix<T, Rows, Cols>
{
private:
size_t n_rows = Rows, n_cols = Cols;
T data[Rows][Cols];
public:
CMatrix() {}
CMatrix(const CMatrix& other);
CMatrix& operator=(const CMatrix& rhs);
CMatrix exp() const;
};
使用可变参数模板
template<class T, int...> class CMatrix;
但是那样只会复制我的大多数成员函数的代码!
【问题讨论】:
-
我会将 Matrix 类拆分为数据部分(您以动态或静态形式处理数据)和“逻辑”部分(您在
data[x][y]上进行操作,无论它是动态的还是静态的)。 -
如果您得到重复的成员函数,请将它们提取到一个公共基类中。这对于 CRTP 来说是一个很好的案例(操作
data的代码是 dame,但data的类型不同)。但是您应该知道T** data对性能不利。如果性能很重要,您想使用一维数组,并自己进行二维地址转换。 -
@n.'pronouns' m 我对 CRTP 不是很熟悉,所以在这里看不到如何使用它的直接解决方案。想用简短的回答来澄清一下吗?基类是否可以访问函数中使用的数据(固定的或动态的)?是的,我将从双指针变为单指针以获得更好的性能,这只是一个示例。
标签: c++ c++11 templates template-specialization class-template