我正在编写一个严重依赖线性代数例程的自定义C++数值库。我也在使用Eigen来满足实际的矩阵运算。我想将我的库与Eigen实现解耦,这样它就不知道Eigen了。这将使我能够将Eigen引用保留在一个位置,并在不久的将来轻松地将线性代数库更改为另一个实现。
在java中,这将相对简单。然而,我在使用Eigen时遇到了困难,因为它使用模板。特别是,我使用的类型是MatrixXd和VectorXd。有人对围绕这些类构建一个包装器有什么建议吗?这个包装器将在Eigen和我的库之间提供一个坚实的边界?
我的第一次尝试是使用composition实现的,因此对MyBaseMatrix的调用指向包含类型(例如MatrixXd(中的调用,如下所示:https://forum.kde.org/viewtopic.php?f=74&t=87072&p=154014&hilit=wrap+eigen#p154014。然而,我怀疑我是否会保留引擎盖下的eigen优化?
这里建议另外两种解决方案:http://eigen.tuxfamily.org/dox-devel/TopicCustomizingEigen.html#ExtendingMatrixBase,(扩展MatrixBase或继承Matrix(。然而,它们似乎不允许我在特征类型和我的数字库之间有严格的边界。此外,扩展MatrixBase似乎不允许运算符重载?
我曾考虑过继承Matrix和MyBaseMatrix(多重继承(,但在试图保留干净的边界时,模板化让我头疼。
有人有这个特定问题的经验吗,或者C++中类似问题的解决方案吗?
从代码设计的角度来看,我不建议这样做,因为线性代数库不可能被替换。因此,封装它很可能没有好处,而且会使代码变得更加复杂。但是,如果您真的想这样做,您可以使用模板专门化。大致如下:
template< typename InternalMatrixType>
class Matrix
{
private:
InternalMatrixType _matrix;
public:
// Example function
float operator[](unsigned index)
{
return _matrix[index];
}
};
对于特定的线性代数库:
template<>
class Matrix<EigenMatrixType>
{
private:
EigenMatrixType _matrix;
public:
// Example function
float operator[](unsigned index)
{
return _matrix.get(index);
}
};
编辑:添加了有关typedefs的信息以澄清用法。基于moodle的以下评论。
在整个库中,您可以对模板类进行typedef。这将允许您使用类似cMatrix
与Matrix<InternalMatrixType>
的内容。
typedef Matrix<InternalMatrixType> cMatrix;