I am trying to implement a templated ODE solver with the following function declaration:
template<class ODEFunction,class StopCondition=decltype(continue_always<ODEFunction>)>
bool euler_fwd(ODEFunction& f,typename State<ODEFunction>::type& x_0
,double t_0,double dt,size_t N_iter
,StopCondition& cond=continue_always<ODEFunction>);
The full source:
/*From SO answer*/
template<class F>
struct State;
template <class R, class... A>
struct State<R (*)(A...)>
{
typedef R type;
};
/*End from SO answer*/
/**Default stop condition. Always return 0 to continue operation.
*/
template<class ODEFunction>
bool continue_always(const typename State<ODEFunction>::type& x_0,double t_0)
{return 0;}
/**Euler forward solver
*/
template<class ODEFunction,class StopCondition=decltype(continue_always<ODEFunction>)>
bool euler_fwd(ODEFunction& f,typename State<ODEFunction>::type& x_0
,double t_0,double dt,size_t N_iter
,StopCondition& cond=continue_always<ODEFunction>)
{
size_t k=0;
while(N_iter)
{
if(cond(x_0,t_0))
{return 1;}
x_0+=dt*f(x_0,k*dt);
--N_iter;
++k;
}
return 0;
}
trying to call euler_fwd with a simple function
double f(double x,double t)
{return x;}
omitting the continue_always predicate, GCC writes
error: invalid use of incomplete type 'struct State'
bool continue_always(const typename State::type& x_0,double t_0)
...
test.cpp:18:47: error: no matching function for call to 'euler_fwd(double (&)(double, double), double&, double&, double&, size_t&)'
EDIT:
If I try to skip the use of default argument for cond:
euler_fwd(testfunc,x_0,t_0,dt,N,continue_always<decltype(testfunc)>);
I still get an error
test.cpp:18:97: note: could not resolve address from overloaded function 'continue_always'