c++ - 如何包装一个函数以适应另一个函数的所需类型

标签 c++ function pointers

考虑以下三个函数:

using phase_t = Eigen::VectorXd;
using rhs_t = phase_t (*)(double const &, phase_t const &);
using step_t = phase_t (*)(rhs_t , phase_t const &, double, double);

Eigen::MatrixXd foo_ee_step(rhs_t rhs, phase_t const &z0);
Eigen::MatrixXd foo_int(step_t step, rhs_t rhs, phase_t const & z0);
Eigen::MatrixXd foo_ee(rhs_t rhs, phase_t const &z0);

它们都有一个 rhs_t 类型的参数。 ,我在上面的第二行中指定了。此外,其中一个函数有一个类型为 step_t 的参数。这取决于 rhs_t 类型的参数.我的问题是我想传递给 foo_ee_step 的变量, foo_intfoo_ee有从
phase_t my_rhs(double const &, phase_t const &, double);

由于我无法更改foo_ee_step , foo_intfoo_ee我尝试使用 lambda 以合适的方式重新定义函数
Eigen::MatrixXd some_function(.....):
    auto better_rhs = [&c](double const & a, phase_t const & b){return my_rhs(a,b,c);};
    return foo_ee(better_rhs, m);

但这会导致
error: cannot convert ‘some_function(....)::<lambda(const double&, const phase_t&)>’ to ‘rhs_t’ {aka ‘Eigen::Matrix<double, -1, 1> (*)(const double&, const Eigen::Matrix<double, -1, 1>&)’}

我认为这是因为我试图传递一个捕获某些东西作为函数指针的 lambda,这似乎是 forbidden ...我读过 here ,可以尝试通过定义仿函数来解决这个问题。但如果我没记错的话,我需要更改 foo_ee_step , foo_intfoo_ee ,我不能.. Soo,我真的不知道如何解决这个问题.. 是否有可能以某种方式将此 lambda 表达式转换为 rhs_t 的形式?有没有其他技术可以解决这个问题?

附言不确定它是否重要,但到目前为止我也尝试过:
  • some_function 中定义另一个函数名为 better_rhs (这显然也不起作用)。
  • 将所有这些封装到一个类中,并使用 foo_ee_step等作为成员函数。然后只需定义另一个成员函数better_rhs并调用my_rhs .. 这导致无法传递非静态成员函数,但必须显式调用它的错误...

  • 任何有关如何进行的提示表示赞赏。

    最佳答案

    这样做的唯一方法是非常hacky。您必须意识到函数指针只是指向函数所在的静态内存位置的指针。因此,不可能添加具有动态或自动存储持续时间(堆或堆栈数据)的状态(即绑定(bind)额外的双参数)。该功能现在需要它所在的位置,但它不能。 (这就是为什么 C 中的通用函数接口(interface)采用 void* 并且函数指针也采用 void* 的原因,因此状态位置作为指向 void 的指针传递,然后解释为函数中的正确类型)

    您可以添加具有静态存储持续时间的状态,即通过以下方式:

    // Interface we want to match
    void print_call(int (*f)()) {
      std::cout << f() << `\n`;
    }
    // Way 1: Globals
    static int data = 0;
    int get_data() { return data; } 
    
    print_call(get_data); // Prints 0
    data = 42;
    print_call(get_data);  // Prints 42
    
    // Way 2: Class statics
    struct state {
      int data = 0;
      static int get_data() { return data; }
    };
    
    print_call(state::get_data); // Prints 0
    state::data = 42;
    print_call(state::get_data); // Prints 42
    

    出于封装和更易于理解的初始化顺序的原因,我更喜欢方式 2。

    请注意,使用静态有其自身的问题。你可能想看看你是否不能以某种方式改变你的设计来摆脱整个问题。

    关于c++ - 如何包装一个函数以适应另一个函数的所需类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59940092/

    相关文章:

    c++ - 为什么在完美转发中不允许隐式转换?

    写入文件时转储​​ C 程序核心

    c++ - C++ 中的抽象类

    python - 任意功能

    使用函数和指针相互改变两个变量

    java - 如何返回函数中的上一个迭代以便重新执行

    c - pthread 空指针转换

    c - 在 C 中使用递归写入文件

    c# - 带有 C++ 客户端和 C# 后端的 Protocol Buffer ?

    c++ - 从十六进制值返回OpenGL #define错误名称的函数