bcf
bcf

Reputation: 2134

Calling pointer to member function from another class

I have a quadrature class for which I would like to be able to pass any integrand into, regardless of whether the function defining the integrand is a free function or a member function of another class. For the latter case, the best progress I've made is like the following.

Class ChiSquared contains a pointer to the GaussQuadrature class and passes a member function to the GaussQuadrature named Quad like so:

double ChiSquared::LowerIncompleteGammaIntegrand(double x) {
  return pow(x, (5/2.0)-1)*exp(-x);
}    

double ChiSquared::LowerIncompleteGamma(double x) {                               
  Quad->Quadrature(&ChiSquared::LowerIncompleteGammaIntegrand, other args...);
  return Quad->getQuad();
}

In the GaussQuadrature template class, the Quadrature function that accepts this call is

template<typename T>
void GaussQuadrature<T>::
Quadrature(double (ChiSquared::*Integrand)(double), other args...)
{
   T val = Integrand(argument);
   ...
   // other math stuff
}

Firstly, This generates the error

error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘Integrand (...)’, e.g. ‘(... ->* Integrand) (...)’

which makes it seem like I need an instance of ChiSquared in the GaussQuadrature class, not the other way around, and I want to avoid this because:

Secondly, I want to decouple the GaussQuadature class from any other classes, as mentioned before. Ideally, ANY function would be able to be passed in as an "integrand" and so I don't want to have to declare a separate Quadrature function for each possible type of class the "integrand" could come from. Could I use some sort of function template here?

Upvotes: 1

Views: 138

Answers (2)

iavr
iavr

Reputation: 7647

You can try

double ChiSquared::LowerIncompleteGamma(double x) {
    std::function<double(double)> f =
        std::bind( &ChiSquared::LowerIncompleteGammaIntegrand, *this, _1 );
    Quad->Quadrature(f, other args...);
    return Quad->getQuad();
}

where GaussQuadrature is modified to take a function<...> argument, or made into a template:

template<typename T>
template<typename F>
void GaussQuadrature<T>::
Quadrature(const F& Integrand, other args...)
{
   T val = Integrand(argument);
   ...
   // other math stuff
}

Here, std::bind binds the ChiSquared object *this with its method LowerIncompleteGammaIntegrand(), giving a function that takes a double argument and returns a double; then, std::function represents this only with its signature double(double), hiding the underlying type ChiSquared.

By the way, some things are apparently missing, e.g. I can't see where parameter x is used in ChiSquared::LowerIncompleteGamma(), or where argument comes from in GaussQuadrature<T>::Quadrature().

Upvotes: 2

Ashalynd
Ashalynd

Reputation: 12573

May be you should omit the other class from the function signature?

template<typename T> void GaussQuadrature<T>::
Quadrature(double (*Integrand)(double), other args...)
{
   T val = Integrand(argument);
   ...
   // other math stuff
}

Upvotes: 0

Related Questions