指向功能成员和非成员的指针

Pointer to function member and non-member

本文关键字:成员 指针 功能      更新时间:2023-10-16

摘要

我有一个可以存储优化问题并在该问题上运行求解器的类。如果求解器失败,我想考虑一个子问题并使用同一求解器(和类)解决。

简介

优化问题在本质上是许多(数学)功能。问题功能是在类外部定义的,但是子问题功能是在类内定义的,因此它们具有不同的类型(例如void (*)void (MyClass::*)

起初,我认为我可以将成员函数投放到非成员指针到功能类型,但我发现我不能。所以我正在寻找其他方式。

示例代码

一个示例代码来模拟我的问题:

#include <iostream>
using namespace std;
typedef void (*ftype) (int, double);
// Suppose foo is from another file. Can't change the definition
void foo (int n, double x) {
  cout << "foo: " << n*x << endl;
}
class TheClass {
  private:
    double value;
    ftype m_function;
    void print (int n, double x) {
      m_function(size*n, value*x);
        }
  public:
    static int size;
    TheClass () : value(1.2), m_function(0) { size++; }
    void set_function (ftype p) { m_function = p; }
    void call_function() {
      if (m_function) m_function(size, value);
    }
    void call_ok_function() {
      TheClass ok_class;
      ok_class.set_function(foo);
      ok_class.call_function();
    }
    void call_nasty_function() {
      TheClass nasty_class;
//      nasty_class.set_function(print);
//      nasty_class.set_function(&TheClass::print);
      nasty_class.call_function();
    }
};
int TheClass::size = 0;
int main () {
  TheClass one_class;
  one_class.set_function(foo);
  one_class.call_function();
  one_class.call_ok_function();
  one_class.call_nasty_function();
}

示例建议,成员函数不能是静态的。另外,我无法重新定义原始问题功能以接收对象。

感谢您的任何帮助。

编辑

我忘了提及。我尝试更改为std ::函数,但是我的原始功能具有10多个参数(这是一个fortran subroutine)。

解决方案

我按照建议将更改为 std::functionstd::bind,但没有进行10个参数的函数重新设计。我决定创建一个中间功能。以下代码说明了我的所作所为,但变量较少。感谢所有人。

#include <iostream>
#include <boost/tr1/functional.hpp>
using namespace std;
class TheClass;
typedef tr1::function<void(int *, double *, double *, double *)> ftype;
// Suppose foo is from another file. Can't change the definition
void foo (int n, int m, double *A, double *x, double *b) {
    // Performs matrix vector multiplication x = A*b, where
    // A is   m x n
}
void foo_wrapper (int DIM[], double *A, double *x, double *b) {
    foo(DIM[0], DIM[1], A, x, b);
}
class TheClass {
    private:
        ftype m_function;
        void my_function (int DIM[], double *A, double *x, double *b) {
            // Change something before performing MV mult.
            m_function(DIM, A, x, b);
        }
    public:
        void set_function (ftype p) { m_function = p; }
        void call_function() {
            int DIM[2] = {2,2};
            if (m_function) m_function(DIM, 0, 0, 0);
        }
        void call_nasty_function() {
            TheClass nasty_class;
            ftype f = tr1::bind(&TheClass::my_function, this, _1, _2, _3, _4);
            nasty_class.set_function(f);
            nasty_class.call_function();
        }
};
int main () {
    TheClass one_class;
    one_class.set_function(foo_wrapper);
    one_class.call_function();
    one_class.call_nasty_function();
}

ps。似乎可以使用

创建一个具有10个以上变量的std::function(编译,但没有测试)
#define BOOST_FUNCTION_NUM_ARGS 15
#include <boost/function/detail/maybe_include.hpp>
#undef BOOST_FUNCTION_NUM_ARGS

但是,为10个以上的参数创建std::bind似乎并不容易。

std::functionstd::bind和lambdas是您想要的。简而言之,功能指针是非常糟糕的事情,应在火中燃烧。长期以来,std::function可以存储任何可以使用正确签名调用的函数对象,您可以使用std::bind或LAMBDA生成一个函数对象,该函数对象可以快速轻松地调用您的成员函数。

编辑:然后,您只需要滚动自己的 std::function等效,支持10多个参数。