【发布时间】:2014-04-26 08:46:10
【问题描述】:
我正在尝试使用以下函数声明实现模板化 ODE 求解器:
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_always 谓词,GCC 写道
错误:不完整类型“结构状态”的无效使用 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&)'
编辑:
如果我尝试跳过对 cond 使用默认参数:
euler_fwd(testfunc,x_0,t_0,dt,N,continue_always<decltype(testfunc)>);
我仍然收到错误
test.cpp:18:97: 注意:无法从重载函数 'continue_always' 解析地址
【问题讨论】:
-
解决这个问题的一种可能方法是写
template <class R, class... A> struct State<R(A...)>而不是template <class R, class... A> struct State<R (*)(A...)>。 -
@Constructor 如果 ODEFunction 是一个函数对象而不是函数指针,是否可以定义非特化的 State 结构体,这样函数对象就不需要为其返回类型包含 typedef函数运算符?
-
这里的典型解决方案是使用
decltype:decltype(f(/* ... */))。但在这种情况下,这是不可能的(至少如此简单),因为据我所知,decltype(f(a, b)) == decltype(a)。
标签: c++ templates metaprogramming