C++ calling a class function inside another function

I am trying to call an outside function (that takes functions as inputs) inside the class by giving class member functions as it's parameters. My code is as follows:

using namespace std;
// This is my external function
double integrate (double a, double b, int steps, double (*func)(double)){
    // code for integration using function pointer
};

Class A
{
    protected:
        vector<double> to_data, from_data;
        int data_size;

    public:
        A (); // constructor

        double calculate_parameter(double t){
            // some class member function that makes use of other class members
        };

        double get_result(double x){
            double sum = 0;
        for (int i=0;i<data_size;i++){
           // this is basically what causes the error
            sum = sum + integrate(to_data[i],from_data[i],1,calculate_parameter);
        }
 };

}

However, it shows me error that the function calculate_parameter cannot be converted. I figured out a way to solve this would be to modify the external function such that it takes a class object as well. Is there a way to do this without instantiating a new class object? Thanks in advance!

Upvotes: 4

Views: 16950

Answers (2)

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385088

The more general approach is to drop these 1970s function pointers and use technology from this millennium:

#include <functional>

double integrate (double a, double b, int steps, std::function<double(double)> f)
{
    // ...
}

class A
{
    double calculate_parameter(double t);

    double get_result(double x)
    {
        using std::placeholders::_1;

        double sum = 0;
        for (int i = 0; i < data_size; i++) {
            sum = sum + integrate(
                to_data[i],
                from_data[i],
                1,
                std::bind(&A::calculate_parameter, this, _1)
            );
        }

        return sum;
    }
};

This provides a simple and easy way to bind to essentially any kind of function, and to "bake in" the this pointer for member functions to the functor itself, without requiring any magic at the eventual callsite (i.e. within integrate, which literally just has to call f!).


An even more "modern" way to do this is to wrap the call to calculate_parameter in a lambda:

template <typename Callable>
double integrate (double a, double b, int steps, Callable f)
{
    // ...
}

class A
{
    double calculate_parameter(double t);

    double get_result(double x)
    {
        double sum = 0;
        for (int i = 0; i < data_size; i++) {
            sum = sum + integrate(
                to_data[i],
                from_data[i],
                1,
                [this](double x) { return this->calculate_parameter(x); }
            );
        }

        return sum;
    }
};

Notice that I've replaced std::function<double(double)> with a deduced template argument Callable; you don't have to do this, but it's conventional not to force a lambda-to-std::function conversion when you don't have to. (Personally I quite like being able to mandate that f will take a double and return a double, without having to rely on its usage to check this.)

Upvotes: 10

Ali Kazmi
Ali Kazmi

Reputation: 1458

This function calculate_parameter must be static. Read more about function objects at Fuction Objects

Upvotes: -1

Related Questions