Abstract
I have a class that stores a optimization problem and runs a solver on that problem. If the solver fails I want to consider a sub-problem and solve using the same solver (and class).
Introduction
An optimization problem is essencially a lot of (mathematical) functions. The problem functions are defined outside the class, but the sub-problem functions are defined inside the class, so they have different types (e.g. void (*) and void (MyClass::*).
At first I thought that I could cast the member function to the non-member pointer-to-function type, but I found out that I cannot. So I'm searching for some other way.
Example Code
An example code to simulate my issue:
#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(); } As the example suggests, the member function can't be static. Also, I can't redefine the original problem function to receive an object.
Thanks for any help.
Edit
I forgot to mention. I tried changing to std::function, but my original function has more than 10 arguments (It is a Fortran subroutine).
Solution
I made the change to std::function and std::bind as suggested, but did not went for the redesign of a function with more 10 arguments. I decided to create an intermediate function. The following code illustrates what I did, but with fewer variables. Thanks to all.
#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. Creating a std::function with more than 10 variables seemed possible (compiled, but I didn't test) with
#define BOOST_FUNCTION_NUM_ARGS 15 #include <boost/function/detail/maybe_include.hpp> #undef BOOST_FUNCTION_NUM_ARGS But creating a std::bind for more than 10 arguments does not seem as easy.