Flexible funtion calling with void* and void** - c++

I wish to write a function, which uses the return value of a double function but/and I want to choose this double function during the function call. My idea is:
#include <iostream>
double linea(double a, double b, double x);
double parabola(double a, double b, double c, double x);
void konjgrad(double (*function)(void** params), void** params);
double linea(double a, double b, double x){
return a*x+b;
}
double parabola(double a, double b, double c, double x){
return a*x*x+b*x+c;
}
void konjgrad(double (*function)(void** params), void** params){
double d;
d=function(params);
std::cout<<d<<std::endl;
}
int main(){
konjgrad(linea(1.6,5.1,2.6));
konjgrad(parabola(2.4,3.1,4,2.6));
return 0;
}
But I stuck in the maze of the pointers. Has anyone an idea, how to solve the problem?

You can use variadic templates and perfect-forwarding to introduce the flexibility you require without any additional run-time overhead:
template <typename TF, typename... TArgs>
void konjgrad(TF&& f, TArgs&&... args)
{
double d;
d = std::forward<TF>(f)(std::forward<TArgs>(args)...);
std::cout<<d<<std::endl;
}
konjgrad can then be called as follows:
konjgrad(linea, 1.6, 5.1, 2.6);
konjgrad(parabola, 2.4, 3.1, 4, 2.6);
wandbox example
Alternatively, you could use lambda expressions and put the burden of binding the arguments on the caller:
template <typename TF>
void konjgrad(TF&& f)
{
double d;
d = std::forward<TF>(f)();
std::cout<<d<<std::endl;
}
konjgrad can then be called as follows:
konjgrad([]{ return linea(1.6, 5.1, 2.6); });
konjgrad([]{ return parabola(2.4, 3.1, 4, 2.6); });
wandbox example

Edited
Based upon Vittorio Romeo review, updated to pass vectors as const reference and added necessary assertion inside the linea and parabola APIs.
Here is little naive approach if you want to avoid variadic functions. As your function interface is clearly defined you can pass in vector or array of double type parameters in your linea and parabola functions.
#include <vector>
using namespace std;
double linea(const std::vector<double>& params)
{
assert(params.size() == 3 /*Linear 3 parameters required*/);
return params[0] * params[1] + params[2];
}
double parabola(const std::vector<double>& params)
{
assert(params.size() == 4 /*Parabola 4 parameters required*/);
return params[0] * params[3] * params[3] +
params[1] * params[3] +
params[2];
}
Little bit modified version of your konjgrad function, it is now returning the double value from the underlying call through function pointer. Please notice that first parameter clearly defines the function interface. Second parameter is the vector of doubles.
double konjgrad(double(*function)(const std::vector<double>&), const std::vector<double>& params)
{
return function(params);//returning value from here
}
Finally here's how you should invoke above defined APIs.
int main(int argc, wchar_t* argv[])
{
std::vector<double> vals;
vals.push_back(1.6);
vals.push_back(5.1);
vals.push_back(2.6);
double v1 = konjgrad(linea, vals);
std::vector<double> parab;
parab.push_back(2.4);
parab.push_back(3.1);
parab.push_back(4.0);
parab.push_back(2.6);
double v2 = konjgrad(parabola, parab);
return 0;
}
Hope this would help.

Related

Convert a function pointer to another having more arguments

Suppose I am trying to use a function which accepts a binary function and calls it with some arguments:
typedef double (*BinaryFunction)(double a, double b);
typedef double (*UnaryFunction)(double a);
// Can't change this
double ExternalFunction(BinaryFunction binaryFunction)
{
return binaryFunction(1, 2);
}
Now suppose a user of my code is going to provide me with a unary function. My goal is to convert it into a binary function so that I can call ExternalFunction with it:
double MyFunction(UnaryFunction unaryFunction)
{
BinaryFunction binaryFunction = /* want a function (a, b) -> unaryFunction(a + b) */;
return ExternalFunction(binaryFunction);
}
How do I do this? Just to be clear, I understand that this would be easy if the unary function were known at compile time, but it's not - it will be an argument to my function. Thanks in advance.
Here's a summary of my attempts. I believe I understand why these don't work, but I'm providing them so you can see what I've been thinking so far.
I can't use a lambda, because I'd have to capture UnaryFunction, and capturing lambdas can't be converted to function pointers:
double MyFunction(UnaryFunction unaryFunction)
{
BinaryFunction binaryFunction = [unaryFunction](double a, double b){ return unaryFunction(a + b); };
return ExternalFunction(binaryFunction);
}
Use std::function ? Can't get that to work either:
void MyFunction(UnaryFunction unaryFunction)
{
std::function<double(double, double)> binaryFunctionTemp = [unaryFunction](double a, double b)
{
return unaryFunction(a + b);
};
BinaryFunction binaryFunction = binaryFunctionTemp.target<double(double, double)>();
ExternalFunction(binaryFunction);
}
What about a function object? Won't work because we'd need a pointer to a member function:
class BinaryFromUnary
{
public:
BinaryFromUnary(UnaryFunction unaryFunction) : unary_(unaryFunction) {};
double operator()(double a, double b)
{
return unary_(a + b);
}
private:
UnaryFunction unary_;
};
void MyFunction(UnaryFunction unaryFunction)
{
BinaryFromUnary functionObject(unaryFunction);
std::function<double(double, double)> binaryFunction = functionObject;
ExternalFunction(binaryFunction.target<double(double, double)>());
}
Even had a go with std::bind (and probably messed it up):
struct Converter {
Converter(UnaryFunction unary) : unary_(unary) {}
double binary(double a, double b) const { return unary_(a + b); }
UnaryFunction unary_;
};
void MyFunction(UnaryFunction unaryFunction)
{
Converter converter(unaryFunction);
std::function<double(double, double)> binaryFunction = std::bind( &Converter::binary, converter, _1, _2);
ExternalFunction(binaryFunction.target<double(double, double)>());
}
Tried a couple of other things along the same lines. Any ideas would be much appreciated.
Use an external variable to hold the unary function.
Include standard disclaimers about how inelegant and non-thread safe this is, etc. but at least this is a hack consistent with the stated requirements:
#include <iostream>
typedef double (*BinaryFunction)(double a, double b);
typedef double (*UnaryFunction)(double a);
// Can't change this
double ExternalFunction(BinaryFunction binaryFunction) {
return binaryFunction(1, 2);
}
namespace foo {
thread_local UnaryFunction unaryFunction;
}
double MyBinaryFunction(double a, double b) {
return foo::unaryFunction(a + b);
}
double MyUnaryFunction(double a) {
return 2 * a;
}
double MyFunction(UnaryFunction unaryFunction) {
foo::unaryFunction = unaryFunction;
BinaryFunction binaryFunction = MyBinaryFunction;
return ExternalFunction(binaryFunction);
}
int main() {
std::cout << MyFunction(MyUnaryFunction) << std::endl; // 6
return 0;
}
I don't know your exact use-case, but there's a chance this might help you:
typedef double (*BinaryFunction)(double a, double b);
typedef double (*UnaryFunction)(double a);
// Can't change this
double ExternalFunction(BinaryFunction binaryFunction)
{
return binaryFunction(1, 2);
}
// If you always know the unary function at compile time:
// Create a wrapper function with the BinaryFunction signature that takes
// a unary function as a NTTP:
template <UnaryFunction unaryFunction>
double wrapper(double a, double b)
{
return unaryFunction(a + b);
}
// Simply use this wrapper to implement MyFunction as follows:
template <UnaryFunction unaryFunction>
double MyFunction()
{
return ExternalFunction(wrapper<unaryFunction>);
}
// Using it:
double unary1(double x) { return x * 2; }
double unary2(double x) { return x * 3; }
int main()
{
std::cout << MyFunction<unary1>() << '\n';
std::cout << MyFunction<unary2>() << '\n';
}
Have a godbolt link to play around with it as well.
Unlike the other answer, this doesn't require a global, but this also only works if you always know your function at compile-time, which there's a good chance you don't, so sorry in advance. Hope it was still interesting.

Passing member function pointer to class-less function

In the code below, I cannot figure out a way of passing a member function to a generic root-finder.
#include <stdio.h>
double OneDimBisector(double (*fun)(float), float a, float b, float tol){
double val;
val = (*fun)(0.5*(b-a)); // actually: do proper bisection
return val;
}
class EOS {
public:
double S_array[10][10]; // actually: filled by constructor
double S(double T, double P);
double T_PS(double P, double S);
double functForT_PS(double T);
double (EOS::*pfunctForT_PS)(double);
double Sseek, Pseek;
};
double EOS::S(double T, double P){
double val = T+P; // actually: interpolate in S_array
return val;
}
double EOS::functForT_PS(double T){
return S(T,Pseek)-Sseek;
}
// Find T from P and S (T is invertible), assuming the intervals are ok
double EOS::T_PS(double P, double S0){
double Tmin = 2., Tmax = 7., T1, tol=1e-8;
pfunctForT_PS = &EOS::functForT_PS;
Sseek = S0;
Pseek = P;
printf("\n %f\n", (*this.*pfunctForT_PS)(4.)); // no problem
T1 = OneDimBisector(pfunctForT_PS, Tmin, Tmax, tol); // wrong type for pfunctForT_PS
return T1;
}
int main() {
double P=3., S=8;
EOS myEOS;
printf("\n %f %f %f\n",P,S,myEOS.T_PS(P,S));
}
I do not want to make the root-finder a member because it is not specific to this class, and the solution of making everything static seems very inelegant. Would someone have an idea? This must be a common situation yet I did not find a relevant post that was also understandable to me.
Thanks!
Edit: Actually, I also meant to ask: Is there a proper, thread-safe way of setting the Pseek variable other than what I did? Just to make it clear: I am doing one-dimensional root finding on a two-dimensional function but fixing one of the two arguments.
One way would be to change the signature of the root finder (add #include <functional>):
double OneDimBisector(std::function<double(float)> f, float a, float b, float tol);
Then invoke it with bind:
T1 = OneDimBisector(std::bind(pfunctForT_PS, this, std::placeholders::_1),
Tmin, Tmax, tol);
This carries a certain overhead. If you don't mind having lots of duplicate code, you can make the function a template:
template <typename Func>
double OneDimBisector(Func f, float a, float b, float tol);
You invoke it the same way, but every time you have a new function type, a new instance of the template is created in your compilate.
The "traditional" solution would be to have a free (or static) function that accepts an additional instance argument.
Update: The "traditional solution":
double OneDimBisector(double(*f)(float, void *), void * data, ...);
double EOSBisect(float f, void * data)
{
EOS * e = static_cast<EOS *>(data); // very "traditional"
return e->functorForT_PS(f);
}
Usage: T1 = OneDimBisector(EOSBisect, this, Tmin, Tmax, tol);
You cannot pass a member function pointer as a function pointer, because the latter lacks the context pointer (the this) to properly invoke the member function pointer.
The general way to solve this (as in the standard C++ library) is to use a template:
template <typename F>
double OneDimBisector(F fun, float a, float b, float tol){
double val;
val = fun(0.5*(b-a));
return val;
}
and pass a function object to it
struct Evaluator
{
EOS* this_;
Evaluator(EOS* this_) : this_(this_) {} // constructor
double operator()(double value) const // call the function
{
return this_->functForT_PS(value);
}
};
T1 = OneDimBisector(Evaluator(this), Tmin, Tmax, tol);
You could also use std::bind1st(std::mem_fun(&EOS::functForT_PS), this), but what it does is just the same as the structure above. (BTW, both std::bind1st and std::mem_fun have been deprecated.)
If you don't like templates, you could accept a polymorphic function instead (e.g. using Boost.Function or std::function in C++11), but it will be slower:
double OneDimBisector(const boost::function<double(double)>& fun,
float a, float b, float tol)
{
return fun(0.5 * (b-a));
}
and finally, if you can use C++11, you could use a lambda function on calling OneDimBisector:
T1 = OneDimBisector([=](double value){ return functForT_PS(value); },
Tmin, Tmax, tol);
The problem you face is that a function pointer is something different to a member funcgtion pointer.
A common (Java World) Approach to circumvent the problem is using the Strategy pattern (fun of the Bisector would be some Implementation of a Strategy).
A common C++-Approach would be using functors/binding, e.g. with boost:
typedef boost::function<double (double)> MyFun;
double OneDimBisector(const MyFun & fun, float a, float b, float tol){
double val;
val = fun(0.5*(b-a)); // actually: do proper bisection
return val;
}
// Calling
T1 = OneDimBisector (boost::bind (&EOS::functForT_PS, *this), Tmin, Tmax, tol));

Question on using class member function as template parameter

I'm reading the book by Daoqi Yang "C++ and Object Oriented Numeric Computing for Scientists and Engineers". He has a similar example to what I am showing below, but the exceptions are the class "P" I define and the second to last line (which doesn't work). My question is: why does my compiler generate and error when I supply the function member f.integrand? What can I do to correct this? The errors being generated are C3867, C2440, and C2973.
Here is the code:
class P{
public:
double integrand(double x){
return (exp(-x*x));
}
};
template<double F(double)>
double trapezoidal(double a, double b, int n)
{
double h=(b-a)/n;
double sum=F(a)*0.5;
for(int i=1;i<n;i++)
{
sum+=F(a+i*h);
}
sum+=F(b)*0.5;
return (sum*h);
}
double integrand2(double x){
return (exp(-x*x));
}
int main(){
P f;
cout<< trapezoidal<integrand2>(0,1,100)<<endl; // this works
cout<< trapezoidal<f.integrand>(0,1,100)<<endl; // this doesn't work
}
Template arguments must be compile-time constant expressions or types, and member functions require special handling anyway. Instead of doing this, use boost::function<> as an argument, and boost::bind to create the functor, e.g.
double trapezoidal(double, double, boost::function<double(double)>);
// ...
P f;
trapezoidal(0, 1, 100, integrand2);
trapezoidal(0, 1, 100, boost::bind(&P::integrand, boost::ref(f)));
If you have 0x-capable compiler, you can use std::function and std::bind instead.
Cat Plus Plus is correct - boost::bind is a good way to do this easily. I've also included an alternate solution with the following snippet of code:
class P{
private:
double a;
public:
double integrand(double x){
return (a*exp(-x*x));
}
void setA(double y){
a = y;
}
void getA(){
cout<<a<<endl;
}
struct integrand_caller {
P* p;
integrand_caller(P& aP) : p(&aP) {};
double operator()(double x) const {
return p->integrand(x);
};
};
};
template <typename Evaluator, typename VectorType>
VectorType trapezoidal(Evaluator f, const VectorType& a, const VectorType& b, int n)
{
VectorType h=(b-a)/n;
VectorType sum=f(a)*0.5;
for(int i=1;i<n;i++)
{
sum+=f(a+i*h);
}
sum += f(b)*0.5;
return (sum*h);
}
double integrand2(double x){
return (exp(-x*x));
}
int main(){
P f[5];
for(int i=0;i<5;i++){
f[i].setA(5*i);
f[i].getA();
cout<< trapezoidal(P::integrand_caller(f[i]),(double)0, (double)1, 100) << endl;
cout<<trapezoidal(boost::bind(&P::integrand,f[i],_1), 0.0, 1.0, 100)<<"\n"<<endl;
}
}

Function pointers working as closures in C++

Is there a way in C++ to effectively create a closure which will be a function pointer? I am using the Gnu Scientific Library and I have to create a gsl_function. This function needs to effectively "close" a couple of parameters available when I create it. Is there a nice trick to create a closure so that I don't have to pass all of them as params in the gsl_function structure? If not, should I just pass in a pointer to an array containing these parameters?
EDIT
I have tried to use boost::bind like this:
#include <gsl/gsl_integration.h>
#include <boost/bind.hpp>
#include "bondpricecalculator.h"
#include "functions.h"
double integrand (double xi, double t, double x, void * p) {
Functions *functions = (Functions *) p;
double vx = functions->v(x);
return functions->rho0(x)*exp(vx * xi - 0.5 * vx * vx * t);
}
double BondPriceCalculator::value(double t, double T, double xi)
{
gsl_integration_workspace * w
= gsl_integration_workspace_alloc (10000);
gsl_function F;
F.function = &boost::bind(integrand, xi, t, _1, _2);
F.params = &functions;
double integral_t;
double integral_T;
double error;
int res = gsl_integration_qags(&F, T, 1e+14, 0, 1e-7, 10000, w, &integral_T, &error);
if(res)
{
throw "Error intgrating";
}
int res = gsl_integration_qags(&F, T, 1e+14, 0, 1e-7, 10000, w, &integral_t, &error);
if(res)
{
throw "Error intgrating";
}
return integral_T/integral_t;
}
but I got the following error message:
/home/ga/svn/PhD/inflation/cpp/ioi/bondpricecalculator.cpp:20: error: cannot convert ‘boost::_bi::bind_t<double, double (*)(double, double, double, void*), boost::_bi::list4<boost::_bi::value<double>, boost::_bi::value<double>, boost::arg<1>, boost::arg<2> > >*’ to ‘double (*)(double, void*)’ in assignment
I found below code at.
http://bytes.com/topic/c/answers/657124-interface-problem
// Use in combination with boost::bind.
template<class F>
static double gslFunctionAdapter( double x, void* p)
{
// Here I do recover the "right" pointer, safer to use static_cast
// than reinterpret_cast.
F* function = static_cast<F*>( p );
return (*function)( x );
}
template<class F>
gsl_function convertToGslFunction( const F& f )
{
gsl_function gslFunction;
const void* p = &f;
assert (p != 0);
gslFunction.function = &gslFunctionAdapter<F>;
// Just to eliminate the const.
gslFunction.params = const_cast<void*>( p );
return gslFunction;
}
and use this like
gslFunction gslF = convertToGslFunction( boost::bind( &Sde::drift, &sde, _1 ) );
Take a look at this simple example of combining boost::bind and boost::function.
I'm guessing from all those "gsl_" prefixes that the library is not C++, but plain C. Which means it doesn't grok C++ closures (functors). You can't pass a C++ functor to a C function. You'll have to pass void pointers around, cross your fingers and reinterpret_cast them into C oblivion.
Though bradgonesurfing has given a nice answer that will work for converting closures into gsl_functions without any further thought, I would like to share with you the idiom for doing a direct translation from C++ into C.
Supposing you have the closure:
double a;
[&a](double x){return a+x;}
You would convert translate this into an equivalent function pointer idiom as follows:
struct paramsAPlusX{
double* a;
paramsAPlusX(double & a_):a(&a_){}
}
double funcAPlusX(double x, void* params){
paramsAPlusX* p= (paramsAPlusX*)params;
return *(p->a) + x;
}
//calling code:
double a;
paramsAPlusX params(a);
gsl_function f;
f.function=funcAPlusX;
f.params=&paramsAPlusX;
//use f here.
Many C libraries use this sort of idiom, and they don't all use a struct for it (they frequently pass it as two separate parameters to the function) so automatic conversion isn't always possible.

std::tr1::function and std::tr1::bind

I have a problem using a very complicated C function in a C++ class (rewriting the C function is not an option). C function:
typedef void (*integrand) (unsigned ndim, const double* x, void* fdata,
unsigned fdim, double* fval);
// This one:
int adapt_integrate(unsigned fdim, integrand f, void* fdata,
unsigned dim, const double* xmin, const double* xmax,
unsigned maxEval, double reqAbsError, double reqRelError,
double* val, double* err);
I need to supply a void function of type integrand myself, and adapt_integrate will calculate the n-dimensional integral. The code in calcTripleIntegral (below) works as a standalone function if func is a standalone function).
I want to pass a (non-static!) class member function as the integrand, as this can be easily overloaded etc...
class myIntegrator
{
public:
double calcTripleIntegral( double x, double Q2, std::tr1::function<integrand> &func ) const
{
//...declare val, err, xMin, xMax and input(x,Q2) ...//
adapt_integrate( 1, func, input,
3, xMin, xMax,
0, 0, 1e-4,
&val, &err);
return val;
}
double integrandF2( unsigned ndim, const double *x, void *, // no matter what's inside
unsigned fdim, double *fval) const; // this qualifies as an integrand if it were not a class member
double getValue( double x, double Q2 ) const
{
std::tr1::function<integrand> func(std::tr1::bind(&myIntegrator::integrandF2, *this);
return calcTripleIntegral(x,Q2,func);
}
}
On GCC 4.4.5 (prerelease), this gives me:
error: variable 'std::tr1::function func' has initializer but incomplete type
EDIT:What is the error in my code? I have now tried compiling with GCC 4.4, 4.5 and 4.6, all resulting in the same error. Either no work has been done on this, or I did something wrong /EDIT
Thanks very much! If I'm not clear enough, I'll gladly elaborate.
PS: Could I work around this without tr1 stuff by using a function pointer to a function defined somewhere in myIntegrator.cpp?
FINAL UPDATE: ok, I was mistaken in thinking TR1 provided a one/two-line solution for this. Bummer. I'm "converting" my classes to namespaces and copypasting the function declarations. I only need one base class and one subclass which reimplemented the interface. C function pointer + C++ class = bad news for me.
Thanks anyways for all the answers, you've shown me some dark corners of C++ ;)
If you are just trying to pass a member function into a c-style callback, you can do that with out using std::t1::bind or std::tr1::function.
class myIntegrator
{
public:
// getValue is no longer const. but integrandF2 wasn't changed
double getValue( double x, double Q2 )
{
m_x = x;
m_Q2 = Q2;
// these could be members if they need to change
const double xMin[3] = {0.0};
const double xMax[3] = {1.0,1.0,1.0};
const unsigned maxEval = 0;
double reqAbsError = 0.0;
double reqRelError = 1e-4;
double val;
adapt_integrate( 1, &myIntegrator::fancy_integrand,
reinterpret_cast<void*>(this),
3, xMin, xMax,
maxEval, reqAbsError, reqRelError,
&val, &m_err);
return val;
}
double get_error()
{ return m_error; }
private:
// use m_x and m_Q2 internally
// I removed the unused void* parameter
double integrandF2( unsigned ndim, const double *x,
unsigned fdim, double *fval) const;
static double fancy_integrand( unsigned ndim, const double* x, void* this_ptr,
unsigned fdim, double* fval)
{
myIntegrator& self = reinterpret_cast<myIntegrator*>(this_ptr);
self.integrateF2(ndim,x,fdim,fval);
}
double m_x
double m_Q2;
double m_err;
};
You have three problems... first you want a std::tr1::function<R (Args..)>, but yours boils down to std::tr1::function<R (*)(Args...)> - so you need two typedefs:
typedef void (integrand) (unsigned ndim, const double *x, void *,
unsigned fdim, double *fval);
typedef integrand* integrand_ptr;
... so the first allows you a compilable function<integrand>. adapt_integrate has to be fixed accordingly:
int adapt_integrate(unsigned fdim, integrand_ptr f, ...);
Next your bind syntax is off, it should be:
std::tr1::bind(&myIntegrator::integrandF2, *this, _1, _2, _3, _4, _5);
The remaining problem is that tr1::function<T> isn't convertible to a function pointer, so you would have to go through a wrapper function, using the void* fdata argument to pass the context. E.g. something like:
extern "C" void integrand_helper (unsigned ndim, const double *x, void* data,
unsigned fdim, double *fval)
{
typedef std::tr1::function<integrand> Functor;
Functor& f = *static_cast<Functor*>(data);
f(ndim, x, data, fdim, fval);
}
// ...
adapt_integrate(1, &integrand_helper, &func, ...);
This is of course assuming that the void* parameter is passed through to the function, if not it would get ugly.
On the other hand, if void* fdata allows to pass context, all that tr1::function stuff is unnecessary and you could just go directly through a trampoline function - just pass this through as the context argument:
extern "C" void integrand_helper (unsigned ndim, const double *x, void* data,
unsigned fdim, double *fval)
{
static_cast<myIntegrator*>(data)->integrandF2(ndim, ...);
}
// ...
adapt_integrate(1, &integrand_helper, this, ...);
Since std::tr1::bind and c-style function pointers don't get along, try this instead. It will work, except that myIntegrator::getValue is not longer thread-safe. If calcTripleIntegral were removed from the interface, this would be even simpler and wouldn't need to use std::tr1::bind or std::tr1::function.
class myIntegrator
{
public:
double getValue( double x, double Q2 ) const
{
return calcTripleIntegral(x,Q2,std::tr1::bind(&Integrator::integrandF2,this));
}
double calcTripleIntegral( double x, double Q2, const std::tr1::function<integrand>& func ) const
{
assert( s_integrator == NULL );
s_integrator = this;
m_integrand = func;
//...declare val, err, xMin, xMax and input(x,Q2) ...//
adapt_integrate( 1, &myIntegrator::fancy_integrand, input,
3, xMin, xMax,
0, 0, 1e-4,
&val, &err);
assert( s_integrator == this);
s_integrator = NULL;
return val;
}
private:
double integrandF2( unsigned ndim, const double *x, void *,
unsigned fdim, double *fval) const;
static double fancy_integrand( unsigned ndim, const double* x, void* input,
unsigned fdim, double* fval)
{
s_integrator->integrateF2(ndim,x,input,fdim,fval);
}
std::tr1::function<integrand> m_integrand;
static const myIntegrator* s_integrator;
};
I want to pass a (non-static!) class member function as the integrand...
You can't. If you search SO for using member functions as callbacks you'll be bound to find useful information including the fact that what you're trying to do, the direct approach anyway, is not possible.
Edit: BTW, one of the problems in your code (there's more of course since what you're trying to do is simply not possible) is that you've passed a function pointer type to function<> when what it expects is a signature. The function template is implemented something like so:
template < typename Signature >
struct function;
// for each possible number of arguments:
template < typename R, typename Arg1, typename Arg2 >
struct function<R(Arg1,Arg2)>
{
... body ...
};
As you can see, passing a function pointer to this kind of thing is simply not going to be understood by the compiler. It's going to try to instantiate the forward declaration and get nowhere. This is of course what the compiler error you're getting means but it doesn't address your fundamental problem, which is that what you're doing will never work.
In a fully C++0x compiler this can be done differently but boost::function and the MSVC one has to be like this. Furthermore, the C++0x version is going to have the same problem that you currently are facing.
Making the assumption that the C-API allows passing a type-agnostic (in the sense that the C-API function doesn't have to know its type but relies on the callback function to know what it requires) context parameter (this is usually the case with callback functions; in this case I suspect the fdata parameter to be something along these lines), pass the function object as part of this context parameter.
It should then look something like this:
#include <iostream>
#include <tr1/functional>
typedef void (*callback_function_t)(void *input, int arg);
struct data_type {
int x;
};
struct context_type {
std::tr1::function<void(data_type const &, int)> func;
data_type data;
};
void callback(data_type const&data, int x) {
std::cout << data.x << ", " << x << std::endl;
}
void callback_relay(void *context, int x) {
context_type const *ctxt = reinterpret_cast<context_type const*>(context);
ctxt->func(ctxt->data, x);
}
void call_callback(callback_function_t func, void *context, int x) {
func(context, x);
}
int main() {
context_type ctxt = { callback, { 1 } };
call_callback(callback_relay, &ctxt, 2);
}
Where call_callback is the C-API function. This way, you can assign anything you want that supports function call syntax to context_type::func, including std::tr1::bind expressions. Also, even though (I feel morally obligated to mention this) it is not, strictly speaking, defined in the standard that calling conventions for C and C++ functions are the same, in practice you could make context_type a class template and callback_relay a function template to make context_type::data more flexible and pass anything you like this way.
That error message makes it sound like you're missing an include for one of the types involved. At least try double-checking your integrand and tr1 includes?
bind works a bit different than you assume I think. You either need to provide a value, or a placeholder for every argument.
For your example this boils down to (with placeholders)
std::tr1::function<integrand> func(std::tr1::bind(&myIntegrator::integrandF2, *this, _1, _2, _3, _4, _5));
Since you're binding a member function, you got an extra (implicit) argument, i.e. the object you call the member function on, so you have six.
For the first you bind the this object, for the other arguments you simply pass placeholders.
On a side note, your member function returns double, while the function declaration returns void.
(for the record, I'm still using an older compiler with little tr1 support, so I only have bind and function experience from using boost, maybe things changed a little for tr1...)