如何不使用工厂方法根据变量状态实例化不同Eigen求解器?
不用工厂方法的简便解决方案
方案1:使用C++17 std::variant(推荐)
std::variant可以存储不同类型的对象,既能让solver在全局作用域保持有效,又不用写复杂的工厂逻辑,完美适配你的场景。
代码示例:
#include <appropriateHeaders.h> #include <variant> #include <string> // 定义包含所有求解器类型的variant using SolverVariant = std::variant< Eigen::SimplicialLLT<Eigen::SparseMatrix<double>>, Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>> // 在这里补充剩下的10种求解器类型 >; int main() { std::string solverType; read_solverType_from_file(solverType); SolverVariant solver; // 根据类型初始化variant if (solverType == "SimplicialLLT") { solver = Eigen::SimplicialLLT<Eigen::SparseMatrix<double>>(); } else if (solverType == "SimplicialLDLT") { solver = Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>>(); } // 补充其他10种类型的判断分支 // 使用std::visit统一调用求解器接口 std::visit([&](auto& s) { // 这里写入所有需要用solver执行的逻辑,比如: s.compute(your_sparse_matrix); auto result = s.solve(your_rhs_vector); // 处理计算结果的逻辑... }, solver); return 0; }
这个方案的优势:
solver在main函数全程有效,不会出现作用域问题- 无需维护基类和工厂代码,实现简洁
- 所有求解器的通用逻辑只需写一次(在
visit的lambda表达式中)
方案2:将业务逻辑内联到判断块中
如果你的项目暂不支持C++17,或者觉得variant太复杂,可以直接把使用solver的代码放到对应的if/else块里。虽然会有代码重复,但实现成本最低:
#include <appropriateHeaders.h> #include <string> // 抽离通用的结果处理逻辑为模板函数,避免重复代码 template<typename SolverType> void process_solution(SolverType& solver, const Eigen::SparseMatrix<double>& mat, const Eigen::VectorXd& rhs) { solver.compute(mat); auto result = solver.solve(rhs); // 统一的结果处理逻辑... } int main() { std::string solverType; read_solverType_from_file(solverType); // 假设已定义好稀疏矩阵和右端项 Eigen::SparseMatrix<double> mat; Eigen::VectorXd rhs; if (solverType == "SimplicialLLT") { Eigen::SimplicialLLT<Eigen::SparseMatrix<double>> solver; process_solution(solver, mat, rhs); } else if (solverType == "SimplicialLDLT") { Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>> solver; process_solution(solver, mat, rhs); } // 补充其他10种类型的判断分支 return 0; }
方案3:基于基类的简化多态
如果上面两个方案都不满足,也可以利用Eigen求解器的公共基类Eigen::SparseSolverBase,用智能指针存储实例。虽然有点接近工厂模式,但实现起来很简单:
#include <appropriateHeaders.h> #include <string> #include <memory> int main() { std::string solverType; read_solverType_from_file(solverType); std::unique_ptr<Eigen::SparseSolverBase<Eigen::SimplicialLLT<Eigen::SparseMatrix<double>>>> solver; if (solverType == "SimplicialLLT") { solver = std::make_unique<Eigen::SimplicialLLT<Eigen::SparseMatrix<double>>>(); } else if (solverType == "SimplicialLDLT") { solver = std::make_unique<Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>>>(); } // 补充其他类型的初始化分支 // 使用求解器 solver->compute(your_sparse_matrix); auto result = solver->solve(your_rhs_vector); return 0; }
内容的提问来源于stack exchange,提问作者1Teaches2Learn
相关产品推荐
相关产品推荐

