【问题标题】:Using GSL functions defined in a structure使用结构中定义的 GSL 函数
【发布时间】:2013-10-03 20:17:26
【问题描述】:

我想编写一个包含所有函数(包括 GSL 函数)和参数的结构体,用于求解 ODE 系统。在主函数中,我只想调用结构中定义的更新函数,以将系统推进一个时间步长。然而,当我尝试这个时,我得到了错误:

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

【问题讨论】:

  • 查找“C++ 指向成员函数的指针”。
  • 谢谢@us2012。使用static int funcS 解决了我的问题。我一定会阅读这个主题以完全理解!
  • 您可以轻松编写一个简单的包装器,以避免将所有需要发送到 GSL 的成员函数声明为静态。

标签: c++ gsl


【解决方案1】:

你不需要直接使用静态函数。相反,您可以编写一个非常通用的包装器。

I believe this is a duplicate questionMy answer 我刚刚链接的问题是基于 here 提供的包装器。但是,我使用模板对其进行了概括,以避免 performance penalty of std::function 由于 std::function 持有的函子的堆分配(原始答案仅警告读者有关 std::function 中涉及的多重间接引起的惩罚实现,这与堆分配引起的问题相比可以忽略不计)。

编辑1:这个问题也讨论here

编辑 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

【讨论】:

  • 感谢您的指导。是否有任何需要注意的警告,特别是因为我想为 ODE 对象数组的每个元素多次调用这些函数? @Managu 提到 here 不建议这样做。
  • 希望EDIT2能帮助解答您的疑虑
猜你喜欢
  • 2012-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-14
  • 1970-01-01
  • 2023-02-21
  • 1970-01-01
  • 2017-11-18
相关资源
最近更新 更多