我有一个非常适合我需要实现的算法的矩阵类。我知道 Eigen,但它不符合我的要求,所以我必须自己做。我一直在使用 Column Major 排序,现在我也有强大的用例来使用 Row Major,所以我想用一个定义排序的额外模板参数来专门化我的模板矩阵类,但我不想打破现有的代码。
这样做的具体效果是使用模板部分特化来生成不同的两个或三个关键类方法,例如operator(int i, int j)
定义不同的排序,类似的概念可以使用预处理器完成#define
,但这不是很优雅,只能编译所有在一种或另一种模式下。这是我要完成的工作的草图:
enum tmatrix_order {
COLUMN_MAJOR, ROW_MAJOR
};
/**
* Concrete definition of matrix in major column ordering that delegates most
* operations to LAPACK and BLAS functions. This implementation provides support
* for QR decomposition and fast updates. The following sequence of QR updates
* are supported:
*
* 1) [addcol -> addcol] integrates nicely with the LAPACK compact form.
* 2) [addcol -> delcol] delcols holds additional Q, and most to date R
* 3) [delcol -> delcol] delcols holds additional Q, and most to date R
* 4) [delcol -> addcol] delcols Q must also be applied to the new column
* 5) [addcol -> addrow] addrows holds additional Q, R is updated in original QR
* 6) [delcol -> addrow] addrows holds additional Q, R is updated in original QR
*/
template<typename T, tmatrix_order O = COLUMN_MAJOR>
class tmatrix {
private:
// basic matrix structure
T* __restrict m_data;
int m_rows, m_cols;
// ...
};
template <typename T>
inline T& tmatrix<T, COLUMN_MAJOR>::operator()(int i, int j) {
return m_data[j*m_rows + i];
}
template <typename T>
inline const T& tmatrix<T, COLUMN_MAJOR>::operator()(int i, int j) const {
return m_data[j*m_rows + i];
}
template <typename T>
inline T& tmatrix<T, ROW_MAJOR>::operator()(int i, int j) {
return m_data[i*m_cols + j];
}
template <typename T>
inline const T& tmatrix<T, ROW_MAJOR>::operator()(int i, int j) const {
return m_data[i*m_cols + j];
}
但编译器会抱怨部分专业化:
/Users/bravegag/code/fastcode_project/code/src/matrix.h:227:59: error: invalid use of incomplete type 'class tmatrix<T, (tmatrix_order)0u>'
/Users/bravegag/code/fastcode_project/code/src/matrix.h:45:7: error: declaration of 'class tmatrix<T, (tmatrix_order)0u>'
但是,如果我完全专门化这些功能,如下所示,它将起作用,但这非常不灵活:
inline double& tmatrix<double, COLUMN_MAJOR>::elem(int i, int j) {
return m_data[j*m_rows + i];
}
这是语言部分模板专业化支持问题还是我使用了错误的语法?