模板化向下转换为派生的 class 并调用相应的方法
Templatize downcasting to the derived class and call the corresponding method
我在 main.cpp 中有一个例程,用户将在其中指定要在程序中执行的模式。指定模式后,将执行相应的块 - 首先将父求解器向下转换为子求解器,然后在子 class.
中调用关联的 solve
方法
std::unique_ptr<SudokuSolver> solver;
if (mode == MODES::SEQUENTIAL_BACKTRACKING)
{
solver = std::make_unique<SudokuSolver_SequentialBacktracking>();
SudokuSolver_SequentialBacktracking* child_solver = dynamic_cast<SudokuSolver_SequentialBacktracking*>(solver.get());
child_solver->solve(board);
}
else if (mode == MODES::SEQUENTIAL_BRUTEFORCE)
{
solver = std::make_unique<SudokuSolver_SequentialBruteForce>();
SudokuSolver_SequentialBruteForce* child_solver = dynamic_cast<SudokuSolver_SequentialBruteForce*>(solver.get());
child_solver->solve(board);
}
else if (mode == MODES::PARALLEL_BRUTEFORCE)
{
int NUM_THREADS = (argc >= 5) ? std::stoi(argv[4]) : 2;
omp_set_num_threads(NUM_THREADS);
#pragma omp parallel
{
#pragma omp single nowait
{
solver = std::make_unique<SudokuSolver_ParallelBruteForce>();
SudokuSolver_ParallelBruteForce* child_solver = dynamic_cast<SudokuSolver_ParallelBruteForce*>(solver.get());
child_solver->solve(board);
}
}
}
else if (mode == MODES::SEQUENTIAL_DANCINGLINKS)
{
solver = std::make_unique<SudokuSolver_SequentialDLX>(board);
SudokuSolver_SequentialDLX* child_solver = dynamic_cast<SudokuSolver_SequentialDLX*>(solver.get());
child_solver->solve();
}
else if (mode == MODES::PARALLEL_DANCINGLINKS)
{
int NUM_THREADS = (argc >= 5) ? std::stoi(argv[4]) : 2;
omp_set_num_threads(NUM_THREADS);
#pragma omp parallel
{
#pragma omp single
{
solver = std::make_unique<SudokuSolver_ParallelDLX>(board);
SudokuSolver_ParallelDLX* child_solver = dynamic_cast<SudokuSolver_ParallelDLX*>(solver.get());
child_solver->solve();
}
}
}
我发现它有点重复代码,所以我想将它们模板化为类似的东西:
template <typename T>
void downCastandSolve(std::unique_ptr<SudokuSolver> solver, SudokuBoard& board)
{
solver = std::make_unique<T>(board);
T* child_solver = dynamic_cast<T*>(solver.get());
child_solver->solve();
}
但是,我收到以下错误消息:
error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = SudokuSolver; _Dp = std::default_delete<SudokuSolver>]’
不确定如何正确地模板化代码部分。希望有人能帮忙!
std::unique_ptr
不可复制。需要参考:
void downCastandSolve(std::unique_ptr<SudokuSolver>& solver, SudokuBoard& board)
// ^
如果 solve
函数是虚拟的,你的代码会更清晰。
此外,构造函数或 solve 方法应该接收电路板引用,但不能同时接收两者。单一方法使代码更易于理解,因为每种算法的工作方式相同。
std::unique_ptr<SudokuSolver> CreateSolver(MODES mode)
{
switch (mode)
{
case MODES::SEQUENTIAL_BACKTRACKING:
return std::make_unique<SudokuSolver_SequentialBacktracking>();
...
}
}
然后假设solve
是虚拟的,代码恢复为:
auto solver = CreateSolver(mode);
solver->solve(board);
solver->get_solution();
任何并行的东西都应该在适当的时候隐藏在 solve
函数中。
通过编写这样的代码,它更易于阅读,并且您不需要额外的模板函数来共享代码,因为您从一开始就避免了重复。
我在 main.cpp 中有一个例程,用户将在其中指定要在程序中执行的模式。指定模式后,将执行相应的块 - 首先将父求解器向下转换为子求解器,然后在子 class.
中调用关联的solve
方法
std::unique_ptr<SudokuSolver> solver;
if (mode == MODES::SEQUENTIAL_BACKTRACKING)
{
solver = std::make_unique<SudokuSolver_SequentialBacktracking>();
SudokuSolver_SequentialBacktracking* child_solver = dynamic_cast<SudokuSolver_SequentialBacktracking*>(solver.get());
child_solver->solve(board);
}
else if (mode == MODES::SEQUENTIAL_BRUTEFORCE)
{
solver = std::make_unique<SudokuSolver_SequentialBruteForce>();
SudokuSolver_SequentialBruteForce* child_solver = dynamic_cast<SudokuSolver_SequentialBruteForce*>(solver.get());
child_solver->solve(board);
}
else if (mode == MODES::PARALLEL_BRUTEFORCE)
{
int NUM_THREADS = (argc >= 5) ? std::stoi(argv[4]) : 2;
omp_set_num_threads(NUM_THREADS);
#pragma omp parallel
{
#pragma omp single nowait
{
solver = std::make_unique<SudokuSolver_ParallelBruteForce>();
SudokuSolver_ParallelBruteForce* child_solver = dynamic_cast<SudokuSolver_ParallelBruteForce*>(solver.get());
child_solver->solve(board);
}
}
}
else if (mode == MODES::SEQUENTIAL_DANCINGLINKS)
{
solver = std::make_unique<SudokuSolver_SequentialDLX>(board);
SudokuSolver_SequentialDLX* child_solver = dynamic_cast<SudokuSolver_SequentialDLX*>(solver.get());
child_solver->solve();
}
else if (mode == MODES::PARALLEL_DANCINGLINKS)
{
int NUM_THREADS = (argc >= 5) ? std::stoi(argv[4]) : 2;
omp_set_num_threads(NUM_THREADS);
#pragma omp parallel
{
#pragma omp single
{
solver = std::make_unique<SudokuSolver_ParallelDLX>(board);
SudokuSolver_ParallelDLX* child_solver = dynamic_cast<SudokuSolver_ParallelDLX*>(solver.get());
child_solver->solve();
}
}
}
我发现它有点重复代码,所以我想将它们模板化为类似的东西:
template <typename T>
void downCastandSolve(std::unique_ptr<SudokuSolver> solver, SudokuBoard& board)
{
solver = std::make_unique<T>(board);
T* child_solver = dynamic_cast<T*>(solver.get());
child_solver->solve();
}
但是,我收到以下错误消息:
error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = SudokuSolver; _Dp = std::default_delete<SudokuSolver>]’
不确定如何正确地模板化代码部分。希望有人能帮忙!
std::unique_ptr
不可复制。需要参考:
void downCastandSolve(std::unique_ptr<SudokuSolver>& solver, SudokuBoard& board)
// ^
如果 solve
函数是虚拟的,你的代码会更清晰。
此外,构造函数或 solve 方法应该接收电路板引用,但不能同时接收两者。单一方法使代码更易于理解,因为每种算法的工作方式相同。
std::unique_ptr<SudokuSolver> CreateSolver(MODES mode)
{
switch (mode)
{
case MODES::SEQUENTIAL_BACKTRACKING:
return std::make_unique<SudokuSolver_SequentialBacktracking>();
...
}
}
然后假设solve
是虚拟的,代码恢复为:
auto solver = CreateSolver(mode);
solver->solve(board);
solver->get_solution();
任何并行的东西都应该在适当的时候隐藏在 solve
函数中。
通过编写这样的代码,它更易于阅读,并且您不需要额外的模板函数来共享代码,因为您从一开始就避免了重复。