gpt4 book ai didi

c++ - 不同的模板类实现但相同的成员函数

转载 作者:行者123 更新时间:2023-12-01 14:13:01 25 4
gpt4 key购买 nike

我有一个模板矩阵类,其中包含一些典型的成员函数,例如 inversedeterminantoperator* 等。我想要在 fixed- 和 dynamic 大小矩阵的模板实现中重用这些成员函数的代码。这可能吗?如果是,如何?

在下面的代码中,与 Eigen 一样,我使用“-1”来表示动态尺寸。是的,我知道我可以为此使用库,但对于我的应用程序,这是不可行的。 由于应用程序 (CUDA) 的性质,无法使用标准功能

是否可以根据模板参数制作具有不同成员变量大小的模板类?例如当 Dynamic_Rows = -1Dynamic_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;

但是那样只会复制我的大多数成员函数的代码!

最佳答案

这是使用 CRTP 进行此类特化的一种非常通用的方法。它不要求有一个简单的单一条件可用于选择数据成员的实现,而其余部分保持不变。

template <class T, class Impl> class MatrixBase {

// data is NOT defined here
Impl exp() const
{
Impl& self = static_cast<Impl&>(*this); // <-- this is magic
Impl result = self; // <-- this is magic
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]); // <-- data is defined in Impl
}
}
return result;
}
// other functions that do not depend on actual type of data
};

template <class T>
class DynamicMatrix : public MatrixBase<T, DynamicMatrix<T>> {
T** data;
// define constructors etc here
};

template <class T, int Rows, int Cols>
class StaticMatrix : public MatrixBase<T, StaticMatrix<T, Rows, Cols>> {
T[Rows][Cols] data;
// define constructors etc here
};

现在您已经拥有 StaticMatrixDynamicMatrix,如果您愿意,可以将它们统一为一个别名模板。

template <class T, int Rows, int Cols>
using CMatrix = std::conditional_t <(Rows >= 0 && Cols >= 0),
StaticMatrix<T, Rows, Cols>,
DynamicMatrix<T>
>;

关于c++ - 不同的模板类实现但相同的成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63500588/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com