I am designing a library for a hierarchical problem. At each stage of the hierarchy there are several "tools" at hand. If at a state N one tool succeeds, the solution is passed to the next (N+1) state. If all tools of stage N fail, we return to the state N-1 (previous) and let the previous stage handle the problem.
I have two possible ideas how to structure this problem. One uses a linked list of templated classes, the other binds directly to the next stage's run function. My question is, is any of these superior to the other (or are both flawed) and why?
The first solution uses templates to create a linked list of templated classes.
template <typename Input, typename Output>
struct BaseSolver
{
virtual boost::optional<Output> run(const Input& _input) = 0;
};
template<typename Input>
struct BaseStage
{
virtual bool runAndRecover(const Input &_input)
{
return true;
}
};
template<typename Input, typename Output>
struct Stage1 : BaseStage<Input>
{
bool run(const Input& _input)
{
for(const auto& solver : solvers_)
{
const auto currentResult = solver->run(_input);
if(currentResult && nextStage->runAndRecover(currentResult.get()))
{
return true;
}
}
return false;
}
std::vector<boost::shared_ptr<BaseSolver<Input, Output>>> solvers_;
BaseStage<Output>* nextStage;
};
This is the other solution. It binds only to the run() function of the next stage
template<typename Input, typename Output>
struct Stage2
{
typedef boost::function<boost::optional<Output> (Input)> SolverFunction;
typedef boost::function<bool(Output)> NextStage;
bool run(const Input& _input)
{
for(const auto& solver : solverFunctions_)
{
const auto solverResult = solver(_input);
if(solverResult && nextStage_(solverResult.get()))
{
return true;
}
}
return false;
}
std::vector<SolverFunction> solverFunctions_;
// will be bind to the next stage::run
NextStage nextStage_;
};
PS: Both versions compile and run as a prototype.