【发布时间】:2021-10-15 15:05:13
【问题描述】:
我正在开发一个用于数学优化的 C++ 框架,并且我正在努力为我的稀疏矩阵表示找到一个好的设计。
基本上:
- 我有两种稀疏矩阵表示:类型 A 和 B;
- 我有(比如说)四个线性求解器,Alan、Alicia、Beth 和 Benjamin。 Alan 和 Alicia 专门使用 A 矩阵,Beth 和 Benjamin 使用 B 矩阵;
- 我想对我的代码进行模板化,以便在运行时选择线性求解器在其余代码中设置所有矩阵的类型(A 或 B 型)(从而直接生成线性系统的矩阵格式正确)。
我尝试了以下(简化的)代码:
template <class MatrixType>
class LinearSolver {
virtual void factorize(const MatrixType& matrix) = 0;
}
class LinearSolverAlan: public LinearSolver<MatrixTypeA> {
void factorize(const MatrixTypeA& matrix) override;
}
class LinearSolverAlicia: public LinearSolver<MatrixTypeA> {
void factorize(const MatrixTypeA& matrix) override;
}
class LinearSolverBeth: public LinearSolver<MatrixTypeB> {
void factorize(const MatrixTypeB& matrix) override;
}
class LinearSolverBenjamin: public LinearSolver<MatrixTypeB> {
void factorize(const MatrixTypeB& matrix) override;
}
求解器的常见超类型是模板类型LinearSolver,所以我也对工厂进行了模板化:
template<class MatrixType>
class LinearSolverFactory {
public:
std::unique_ptr<LinearSolver<MatrixType> > create(const std::string& solver_name) {
if (solver_name == "alan") {
return std::make_unique<LinearSolverAlan>();
}
else if (...) {
...
}
}
};
然后在更高级别上,我使用正确的求解器名称和模板参数调用 LinearSolverFactory::create()。
但是它不会编译(std::unique_ptr<LinearSolverAlan> 不能转换为std::unique_ptr<LinearSolver<MatrixTypeA> >)。我的模板不够好,看问题能否解决。
感谢您的帮助:)
查理
【问题讨论】:
-
两个分支都必须有效,但同时只有一个。为什么要通过模板参数和字符串参数选择哪种类型?其中一个是否足以决定工厂应该返回哪种类型的求解器?
-
感谢您的回复。线性求解器是第三方代码,可能超过 2 个。它们每个都使用 A 或 B 矩阵。这就是我给他们起名字的原因;我们选择求解器,它反过来应该修复矩阵类型。
-
但是只能调用
LinearSolverFactory<TypeA>::create("alan")而且只能调用LinearSolverFactory<TypeB>::create("beth"),字符串好像是多余的,还是我误会了什么? -
模板和类型是编译时的事情。根据求解器的运行时选择,您不能将“未知”类型的矩阵转换为正确的矩阵类型。您可以在编译时做出选择,并且可以丢弃带有名称的字符串。或者您可以在运行时做出选择,并使用多态性。
-
super 说了什么,但是您已经在编译时通过模板参数选择了矩阵类型。也许添加一个您计划如何使用工厂的示例将有助于澄清
标签: c++ templates inheritance matrix factory