Pointer to a member of a function and non-member

annotation

I have a class that stores the optimization problem and runs the solver of this problem. If the solver fails, I want to consider the sub-problem and solve it using the same solver (and class).

Introduction

The optimization problem is essentially related to (mathematical) functions. The task functions are defined outside the class, but the subtask functions are defined inside the class, so they have different types (for example, void (*) and void (MyClass::*) .

At first I thought I could apply a member function to a pointer-type of non-member, but I found that I could not. Therefore, I am looking for another way.

Code example

Sample code to simulate my problem:

 #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 shows, a member function cannot be static. Also, I cannot override the original function of the problem to get the object.

Thanks for any help.

Edit

I forgot to mention. I tried switching to std :: function, but my original function has more than 10 arguments (this is a Fortran routine).

Decision

I made changes to std::function and std::bind as suggested, but did not redesign the function with more than 10 arguments. I decided to create an intermediate function. The following code illustrates what I did, but with fewer variables. Thanks to everyone.

 #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 mxn } 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 have not tested) with

 #define BOOST_FUNCTION_NUM_ARGS 15 #include <boost/function/detail/maybe_include.hpp> #undef BOOST_FUNCTION_NUM_ARGS 

But creating std::bind for more than 10 arguments does not look so easy.

+4
source share
1 answer

std::function , std::bind , and lambdas are what you are looking for. In short, function pointers are very bad things and should be burned in flames. In long, std::function can store any function object that can be called with the correct signature, and you can use std::bind or lambda to create a function object that quickly and easily calls your member function.

Edit: then you just need to collapse your own equivalent to std::function , which supports more than 10 arguments.

+3
source

Source: https://habr.com/ru/post/1443086/


All Articles