c++ - CRTP:确定基类函数中的派生类类型以允许代码重用
问题描述
假设我有一个矩阵的 CRTP 模板类
template<class T, class Derived>
class MatrixBase{
private:
//...
public:
Derived some_function(const Derived &other){
Derived& self = (Derived&)*this; // In my application I cant use static_cast.
// Some calculations..., which will determine the below
// defined variables "some_number_of_rows" and "some_number_of_cols"
// If Derived = DynamicMatrix<T>, then result should be declared as:
DynamicMatrix<T> result(some_number_of_rows, some_number_of_cols);
// while if Derived = StaticMatrix<T, Rows, Cols>, then result should be declared as:
StaticMatrix<T, some_number_of_rows, some_number_of_cols> result;
// Perform some more calculations...
return result;
}
};
template<class T>
class DynamicMatrix{
private:
size_t n_rows, n_cols;
T *data;
public:
DynamicMatrix(const size_t n_rows, const size_t n_cols);
// ...
};
template<class T, int Rows, int Cols>
class StaticMatrix{
private:
size_t n_rows = Rows, n_cols = Cols;
T data[Rows * Cols];
public:
StaticMatrix() {}
// ...
};
如何检查派生类类型MatrixBase::some_function(const Derived &other)
以在两个派生类中使用此基函数?,防止需要在这些类中单独重新定义/覆盖/代码重复。在这种情况下,基本上只有result
矩阵的声明需要我检查派生类类型,因为声明是不同的,具体取决于它是固定大小的矩阵还是动态矩阵。也欢迎除类型检查之外的其他解决方案。
注意:由于我的应用程序的性质,我不能使用标准功能。
编辑:示例函数中的some_number_of_rows
andsome_number_of_cols
通常不是 constexpr,因为它们取决于对象矩阵的函数和大小。例如,对于一个transpose
函数,结果必须具有维度<Derived.n_cols, Derived.n_rows
,并且在按列点积的情况下,<1, Derived.n_cols>
。
解决方案
这是一个具有挑战性的问题。基本上,some_number_of_rows
并且some_number_of_cols
必须在constexpr
的情况下StaticMatrix
,并且不能在constexpr
的情况下DynamicMatrix
。
一种解决方案是将新矩阵的创建委托给派生类。它将按constexpr
或不进行大小计算constexpr
,以适合它的为准。
另一种是在 CRTP 类中进行大小计算两次,一次 asconstexpr
和一次 not constexpr
,并将两个结果都传递给派生对象创建函数:constexpr
作为模板参数传递,而非constexpr
作为常规参数传递。创建函数专门用于静态和动态矩阵。静态版本忽略非constexpr
参数,反之亦然。
推荐阅读
- angular - Karma Jasmin - 为什么即使没有测试用例,我的测试用例也会随机失败?
- arrays - 获取数组bash raspbian中命令的每一行
- java - 如何使用 okhttp 更改连接请求的标头
- c++ - 当值包含引号(“)时如何返回json字符串
- php - 通过soapclient向需要CDATA的服务发送SOAP请求的问题
- java - Quarkus Keycloak 管理员客户端
- ruby-on-rails - 在节目中找不到 'id'=number 的用户
- javascript - Puppeteer 不会保存无头 Ubuntu 的截图
- python - 带有猴子补丁实例方法的 Python 复制对象
- python-3.x - 获取 ValueError:索引包含重复的条目,无法重塑