Class member function pointer that uses another class member [duplicate] - c++

This question already has answers here:
C++ function pointer (class member) to non-static member function
(6 answers)
Closed 10 years ago.
I'm trying to make a code that find the numerical derivation of a function.
I also have a polynomial class described as follows:
class polynomial
{
public:
polynomial(Vector, int);
polynomial();
~polynomial();
double returnValue(double);
void print();
private:
int Degree;
Vector Coeficients;
};
my numerical derivation have the following prototype:
double numericalDerivation( double (*F) (double), double x);
I want to pass the returnValue method into the numericalDerivation, is that possible?

Yes, it is possible, but don't forget it is a member function: you won't be able to call it without having a (pointer to) an object of type polynomial on which to invoke it.
Here is how the signature of your function should look like:
double numericalDerivation(double (polynomial::*F)(double), polynomial* p, double x)
{
...
(p->*F)(x);
...
}
Here is how you would invoke it:
double d = ...;
polynomial p;
numericalDerivation(&polynomial::returnValue, &p, d);
Alternatively, you could use an std::function<> object as a parameter of your function, and let std::bind() take care of binding the object to the member function:
#include <functional>
double numericalDerivation(std::function<double(double)> f, double x)
{
...
f(x);
...
}
...
double d = ...;
polynomial p;
numericalDerivation(std::bind(&polynomial::returnValue, p, std::placeholders::_1), d);

Related

Convert a member function pointer to standard C function with multiple arguments [duplicate]

This question already has answers here:
Convert C++ function pointer to c function pointer
(7 answers)
Closed 5 years ago.
I am trying to convert a member function pointer to standard C function pointer without success.
I tried different methods but I miss something.
My problem is that I need to call a library's function that takes as argument a functor:
void setFunction(void(*cbfun)(float*,int,int,int,int)){ ... }
inside a class in this way:
class base_t {
public:
void setCallback(){
setFunction(&_callback);
}
private:
void _callback(float * a, int b, int c, int d, int e) { ... }
};
Unfortunately, the _callback() function cannot be static.
I'm also tried to use std::bind but without fortune.
Is there any way I can pass the member to the function?
I am trying to convert a member function pointer to standard C function pointer without success.
Short answer: You cannot.
Longer answer: Create a wrapper function to be used as a C function pointer and call the member function from it. Remember that you will need to have an object to be able make that member function call.
Here's an example:
void setFunction(void(*cbfun)(float*,int,int,int,int)){ ... }
class base_t;
base_t* current_base_t = nullptr;
extern "C" void callback_wrapper(float * a, int b, int c, int d, int e);
class base_t {
public:
void setCallback(){
current_base_t = this;
setFunction(&callback_wrapper);
}
private:
void _callback(float * a, int b, int c, int d, int e) { ... }
};
void callback_wrapper(float * a, int b, int c, int d, int e)
{
if ( current_base_t != nullptr )
{
current_base_t->_callback(a, b, c, d, e);
}
}

Passing class field to member function

I have a class which has a few large fields (say, some big matrices) and has member functions to compute these matrices (the actual number of the matrices is bigger, of course)
class MyClass {
protected:
MatrixType m_11, m_12;
public:
void compute_m_11(double x);
void compute_m_12(double x);
}
Now, the computation code is very similar, and the most complex part is correct indexing of the matrix elements (which is the same for all the matrices involved). So I was thinking about splitting the indexing and the computation into separate functions: a compute_matrix function which will perform the indexing and call a compute_element function for each set of indexes in the matrix. This would greatly improve code readability and ease debugging.
So the compute_matrix function would take a MatrixType reference to the class field which I need to fill in and a std::function which would perform the actual computation. I obviously want to avoid writing anything that will involve additional copying of the matrices, since they can be quite large.
So, the questions are:
Is it legal/efficient to pass a reference to a class field to a class member function?
If so, do I need to use std::bind to pass the computation member functions? The compute_elements functions need to access some other fields of MyClass.
This is what I have in mind:
class MyClass {
protected:
MatrixType m_11, m_12;
double compute_elements_m11(int i, int j, double x);
double compute_elements_m12(int i, int j, double x);
void compute_matrix(MatrixType &m, double x, std::function<double(int, int, double) > f);
public:
void compute_m_11(double x) {compute_matrix(m_11, x, compute_elements_m11);};
void compute_m_12(double x) {compute_matrix(m_12, x, compute_elements_m12);};
}
It is legal (and not that uncommon) to pass a member reference, but your function type is wrong.
You could use std::bind, or you could use a plain pointer-to-member:
class MyClass {
protected:
MatrixType m_11, m_12;
double compute_elements_m11(int i, int j, double x);
double compute_elements_m12(int i, int j, double x);
void compute_matrix(MatrixType &m, double x, double (MyClass::*f) (int, int, double);
public:
void compute_m_11(double x) {compute_matrix(m_11, x, &MyClass::compute_elements_m11);};
void compute_m_12(double x) {compute_matrix(m_12, x, &MyClass::compute_elements_m12);};
};
std::bind and std::function gives a more flexible implementation though.
Sure it's not uncommon to pass a class attribute to an internal member function and you can also use std:bind to call the member function, but the question is do you really need that or can you just use a simple "if" or something similar to decide what to use? I'd say it depends on how many choices your code path has to decide that better.
Why would you pass a reference to a class field to a class member function? A better solution would be to implement a get method and use that in the compute_matrix function. Your class will then look something like this:
class MyClass {
protected:
MatrixType m_11, m_12;
double compute_elements_m11(int i, int j, double x);
double compute_elements_m12(int i, int j, double x);
void compute_matrix(double x, std::function<double(int, int, double) > f);
public:
void compute_m_11(double x) {compute_matrix(x, compute_elements_m11);};
void compute_m_12(double x) {compute_matrix(x, compute_elements_m12);};
MatrixType& getMatrixType_11( return m_11 );
MatrixType& getMatrixType_12( return m_12 );
}

Pointer to member function of an object [duplicate]

This question already has answers here:
Function pointer to member function
(8 answers)
Closed 5 years ago.
I would like to integrate a function with gsl. Therefor I have to define a function f (the integrant, which has to be of the form double (*)(double, void*)). For the call of the gsl integration method I need to define a struct, which contains a pointer to a function (this struct is called gsl_function).
gsl_function F;
F.function = &MyClass::my_f;
The function f must be implemented in a class (in the same class from which the integration procedure should be called). How can I assign the pointer above correctly, since the 2nd line is not compiling and leads to the error:
cannot convert ‘double (MyClass::*)(double, void*)’ to ‘double (*)(double, void*)’ in assignment.
Here the definition of my_f
struct my_f_params { double a; double b;};
double my_f (double x, void * p) {
struct my_f_params * params = (struct my_f_params *)p;
double a = (params->a);
double b = (params->b);
return 1.0/(sqrt(a * (1.0 + x)*(1.0 + x)*(1.0 + x) + (1-a) * std::pow((1.0 + x), (3.0 * (1.0 + b)))));
}
which has to be of the form double (*)(double, void*)
Non static member function declarations involve the implicit call scope qualifier as stated in the error message
double (MyClass::*)(double, void*)
// ^^^^^^^^^
This is different from the callback function pointer definition.
What you probably can do with such interface, is to pass the this pointer through the void* argument of the callback function:
class MyClass {
static double func(double d,void* thisPtr) {
MyClass* myClass = (MyClass*)thisPtr;
// do something
}
};
As mentioned in the documentation you can set the params like that in a wrapper class:
class gsl_function_wrapper {
public:
gsl_function_wrapper() {
F.function = &func;
F.params = this;
}
private:
gsl_function F;
double a;
double b;
static double func(double d,void* thisPtr) {
gsl_function_wrapper* myWrapper = (gsl_function_wrapper*)thisPtr;
// do something with a and b
foo(d,myWrapper->a,myWrapper->b);
}
};

Why does this boost bind non-static member function fail? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Why does the following compiles i.e. passing a free function as parameter with the right signature:
inline double free_adapter_f(unsigned n, const double *x, double *grad, void *d) {
return 0.0;
}
nlopt::opt opt(nlopt::LN_NELDERMEAD, X.size());
opt.set_min_objective(free_adapter_f, NULL);
whereas this other doesn't compile i.e. passing the result of boost::bind a class member function with the same signature:
template<class Space, class Solution, class Oracle>
inline double NelderMead<Space, Solution, Oracle>::adapter_f(unsigned n, const double *x, double *grad, void *d) {
return 0.0;
}
nlopt::opt opt(nlopt::LN_NELDERMEAD, X.size());
opt.set_min_objective(boost::bind(&NelderMead::adapter_f, this, ::_1, ::_2, ::_3, ::_4), NULL);
The error message is the following:
nelder_mead.h(98): error: no instance of overloaded function "nlopt::opt::set_min_objective" matches the argument list
argument types are: (boost::_bi::bind_t<double, boost::_mfi::mf4<double, NelderMead<TestSpace, VectorXd, oracle_f>, unsigned int, const double *, double *, void *>, boost::_bi::list5<boost::_bi::value<NelderMead<TestSpace, VectorXd, oracle_f> *>, boost::arg<1>, boost::arg<2>, boost::arg<3>, boost::arg<4>>>, long)
object type is: nlopt::opt
opt.set_min_objective(boost::bind(&NelderMead::adapter_f, this, ::_1, ::_2, ::_3, ::_4), NULL);
UPDATE: the overloaded set_min_objective are:
typedef double (*func)(unsigned n, const double *x, double *grad, void *f_data);
typedef double (*vfunc)(const std::vector<double> &x, std::vector<double> &grad, void *f_data);
void set_min_objective(func f, void *f_data);
void set_min_objective(vfunc vf, void *f_data);
You need to define set_min_objective which accepts boost::function as first parameter:
typedef boost::function<double (unsigned n, const double *x, double *grad, void *f_data)> func_t;
...
void set_min_objective(func_t, void*);
...
another thing - you'd better not to use NULL
Here is a simple example, which demonstrates your problem:
#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>
namespace g
{
typedef int (*func)(int a, int b, int c);
void bar(func f)
{
std::cout << "g::bar:: called" << (*f)(10, 20, 30) << std::endl;
}
// Disable the over load below and you will get the same error
void bar(boost::function<int(int, int, int)> f)
{
std::cout << "g::bar:: called" << f(10, 20, 30) << std::endl;
}
}
template <typename A, typename B, typename C>
class foo
{
public:
int bar(int a, int b, int c) const
{ return a + b + c; }
void call()
{
g::bar(boost::bind(&foo::bar, this, ::_1, ::_2, ::_3));
}
};
int main(void)
{
foo<int, double, int> f;
f.call();
return 0;
}
Main reason is that boost::function<> is not convertible to a function pointer, so you need to provide an overload which accepts this (as above.)
EDIT: just to clarify things a little further. boost::bind() does not explicitly return a boost::function<>, however, the object it returns can be stored in the correct instantiation of boost::function<>, in the above case, the correct instantiation is boost::function<int(int, int, int)>.
Normally you would only need to resort to storing it in a boost::function if you were interested in propagating it (without a template) or storing it for later use. In this case, as you are passing the result of the bind(), you need to have the correct overload to accept the returned object from boost::bind(), and the easiest way to do this without resorting to templates is to accept a boost::function (as above.)
Normally, I'm pragmatic, so I would resort to this (without knowing what you are wanting to do with f) where possible.
template <typename F>
double set_min_objective(F f, ...)
{
}
Then you are agnostic, of course purists will have other opinions.
NOTE: A nice thing with boost::function<> is that you can store a non-member function pointer in one too (as long as the signature matches.) So in reality you only need a version of your function which accepts the correct boost::function<> and it will work in both cases (member function with boost::bind() and non-member function.)
EDIT2: Okay, given the additional information, you have to resort to the following mechanism, you need to have a non-member function of your class, which will then delegate to the member function, for example:
<>
class NelderMead
{
static double delegate_f(unsigned n, const double *x, double *grad, void *f_data)
{
// I'm assuming here the frame work passed you whatever you gave in f_data
NelderMead* inst = reinterpret_cast<NelderMead*>(f_data);
return inst->adapter_f(n, x, grad);
}
double adapter_f(unsigned n, const double *x, double *grad)
{
}
void set()
{
nlopt::opt opt(nlopt::LN_NELDERMEAD, X.size());
opt.set_min_objective(delegate_f, this); //<-- here pass the instance as the additional data
}
};
This is a typical pattern employed by third-party libraries which are meant to be agnostic to user code.
Both overloads of set_min_objective expect a pointer-to-function as the first parameter, but the object returned by boost::bind is not a pointer-to-function, it's a function object.
boost::bind returns a function object that stores the target function and any bound arguments, it doesn't synthesize a function and return a pointer to it, or magically turn a pointer-to-member-function into a pointer-to-function. That would be magic.

Pointer to function member and non-member

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.
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 fire. In long, std::function can store any function object which can be called with the correct signature, and you can use std::bind or a lambda to generate a function object that calls your member function quickly and easily.
Edit: Then you will just have to roll your own std::function equivalent that supports more than 10 arguments.