我想编写一个包含所有函数(包括GSL函数)的结构和用于求解ODE系统的参数。从main函数中,我只想调用struct中定义的更新函数,以便将系统推进一个时间步。然而,当我尝试这个时,我得到错误:
Line 27, ERROR: cannot convert ‘ODE::funcS’ from type ‘int (ODE::)(double, const double*, double*, void*)’ to type ‘int (*)(double, const double*, double*, void*)’ Below is a minimal code. \
以下是我的代码的最小版本:
#include <iostream>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_odeiv.h>
struct ODE
{
void update(double dt)
{
// code to advance ODE solution by one time-step dt
}
int
funcS (double t, const double y[], double f[],
void *params)
{
return GSL_SUCCESS;
}
double mu = 10;
gsl_odeiv_system sysS;
void
initializeSys()
{
sysS.function = funcS; //Line 27
}
};
int
func (double t, const double y[], double f[],
void *params)
{
return GSL_SUCCESS;
}
int main()
{
// GIVES ERROR
ODE mySys;
mySys.update(0.01);
// WORKS
double mu = 10;
gsl_odeiv_system sys;
sys.function = func;
return 0;
}
答案 0 :(得分:2)
您不需要直接使用静态功能。相反,你可以编写一个非常通用的包装器。
I believe this is a duplicate question。 My answer我刚刚链接的问题基于提交的{?3}}包装器。但是,我使用模板来概括它以避免由于std :: function保存的仿函数的堆分配而导致here(原始答案仅警告读者有关std中涉及的多个间接引起的惩罚: :函数实现,与堆分配引起的问题相比,这可以忽略不计。)
编辑1:此问题也在讨论performance penalty of std::function
编辑2(回答您在第一条评论中提出的问题)。第一个警告是,在GSL完成计算之前,您必须确保不删除std::function
保留的任何内容。此外,@ Managu指出,在GSL工作时,包装器本身不得超出范围。如果您仔细编码,这并不难实施。坏代码示例:
// BAD PROGRAM - EXAMPLE OF WHAT YOU MUST NOT DO. DO NOT COPY THIS CODE
// HERE THE WRAPPER GETS PREMATURELY OUT OF SCOPE => CRASH
gsl_function *F
auto ptr = [](double x)->double{return 2*x;};
std::function<double(double)> FF1(std::cref(ptr))
{
gsl_function_pp Fp(FF1);
F = static_cast<gsl_function*>(&Fp);
}
(...)
// CALL GSL