我正在编写一个很大程度上依赖于线性代数例程的自定义C ++数值库。我也在使用Eigen来满足实际的矩阵运算。我想将我的库与Eigen实现分离,以便它不知道Eigen。这将允许我将Eigen引用保存在一个地方,并且可以在不久的将来轻松地将线性代数库更改为另一个实现。
在java中,这会相对简单。但是我在使用模板时遇到了困难。特别是我使用MatrixXd和VectorXd类型。有没有人建议围绕这些类构建一个包装器,它将在Eigen和我的库之间提供一个可靠的边界?
我的第一次尝试是使用合成实现的,因此对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 ++中类似问题的解决方案有任何经验?
答案 0 :(得分:0)
我不建议从代码设计的角度来做这件事,因为线性代数库不是你可能会替换的东西。因此封装它很可能不会有益,并会使您的代码更复杂。但是,如果您真的想这样做,您将使用模板专业化。以下内容:
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);
}
};
编辑:添加了有关typedef的信息以阐明用法。基于moodle的以下评论。
然后在整个库中,您可以键入dede模板类。这样您就可以使用cMatrix
vs Matrix<InternalMatrixType>
。
typedef Matrix<InternalMatrixType> cMatrix;