2014-04-26 2 views
0

Я пытаюсь реализовать шаблонный ОДУ решатель с помощью следующей функции декларации:Построение шаблонных ОДУ решатель

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>); 

Полный источник:

/*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; 
    } 

пытается вызвать euler_fwd с простой функцией

double f(double x,double t) 
    {return x;} 

Опуская предикат continue_allways, GCC пишет

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:

Если я пытаюсь пропустить использование аргумента по умолчанию для конд:

euler_fwd(testfunc,x_0,t_0,dt,N,continue_always<decltype(testfunc)>); 

я все еще получаю ошибку

test.cpp:18:97: note: could not resolve address from overloaded function 'continue_always'

+1

Одним из возможных путей решения этой проблемы заключается в написании 'шаблон <класс R, класс ... A> структура Государственного ' вместо 'шаблон <класс R, класс ... A> структура государственного ' , – Constructor

+0

@Constructor Если ODEFunction является объектом функции вместо указателя функции, можно ли определить неспециализированную структуру состояния, чтобы объект функции не должен содержать typedef для возвращаемого типа его оператора функции? – user877329

+0

Типичным решением здесь является использование 'decltype':' decltype (f (/ * ... * /)) '. Но в этом случае это невозможно (так просто, по крайней мере), потому что 'decltype (f (a, b)) == decltype (a)', как я понимаю. – Constructor

ответ

0

Вместо того, чтобы пытаться манипулировать типами функций (типы f, cond), почему бы не сделать состояние аргументом шаблона?

#include <cstdlib> // for size_t 
#include <functional> 

template<class R> 
bool continue_always(const R& x_0,double t_0) 
{return 0;} 

template<class R> 
bool euler_fwd(std::function<R(const R &)> f,R& x_0 
    ,double t_0,double dt,size_t N_iter 
    ,std::function<bool(const R&, double)> cond=continue_always<R>) 
{ 
    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; 
} 
+0

Какой тип R (const R &). Никогда не видел этот синтаксис до – user877329

+0

'std :: function ' - тип вызываемого объекта, который принимает 'const R &' и возвращает 'R'. Взгляните на документацию для 'std :: function'. –

+0

Я ссылался на параметр типа, который присваивается этому шаблону. – user877329

Смежные вопросы