I have the below class that yields this error for the lines I commented. The error I get is

ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say ‘&FD_Euro_Put::f’

The signature for Forward Euler is:

Eigen::MatrixXd B::Forward_Euler(double (*f)(double), double (*gleft)(double), double (*gright)(double))

And my class is:

class C
{
protected:
    A x;
    B y;
    double a;
    double b;
    Eigen::MatrixXd u;

public:
    double f(tau)
    {
        return tau*a*x.x1;
    }
    double gleft(double tau)
    {
        return tau*b*x.x2
    }
    double gright(double tau)
    {
        return tau*a*b;
    }
    C(): x(), y(), a(0), b(0){}
    C(char y1, double y2, double y3, double y4, double x2,
            double x3, double x4, double x5, double x6, double x7):
            x(x1, x2, x3, x4, x5, x6, x7)
    {
        double Xleft = x1*x2;
        double Xright = x1*x3;
        double Tauf = x1*x1;
        double NN = floor((x1/x2);
        a = x1*x2 - 0.5;
        b = x1*x2 + 0.5;

        b = C(y1, NN, Xleft, Xright, Tauf, Alpha); 
        u.resize(pde.N+1, pde.M+1); 
        if(fdtype == 'f')
            u = b.Forward_Euler(&f, &gleft, &gright); //error
        else if(fdtype == 'b')
            u = b.Backward_Euler(&f, &gleft, &gright); //error
        else if(fdtype == 'c')
            u = b.Crank_Nicolson(&f, &gleft, &gright); //end problem area
        else
            cout << "Incorrect choice for finite difference type!" << endl;
    }

Recommended Answers

All 2 Replies

The problem is that your Forward_Euler method takes function pointers as parameters, but "f", "gleft" and "gright" are member functions of the class C. These are not the same thing and thus, you get errors.

There are a number of options to solve the problem.

1) You could make the Forward_Euler function take member function pointers, but then it must be member functions of class C. What I mean is that you'd need this signature for the Forward_Euler method:

Eigen::MatrixXd B::Forward_Euler(C& c_obj, double (C::*f)(double), double (C::*gleft)(double), double (C::*gright)(double));

And then, within that function, you would call the functions as so:

double a = c_obj.*f(1.0);
double da = c_obj.*gleft(1.0);

This solution might not be practical if you want to use that function with function pointers that are not members of the class C.

2) In the OOP style, you could create a base class for a class that contains these three functions, as so:

class DifferentiableFunction {
  public:
    virtual double f(double) = 0;
    virtual double gleft(double) = 0;
    virtual double gright(double) = 0;
};

And then, your C class would inherit from that base class, and then you can make the Forward_Euler method with the following signature:

Eigen::MatrixXd B::Forward_Euler(DifferentiableFunction& f_obj);

And call the function as this:

    if(fdtype == 'f')
        u = b.Forward_Euler(*this); 
    ...

3) You could make the Forward_Euler method to take in std::function objects (which are generic function wrappers provided by the more recent compilers (C++11)). As so:

Eigen::MatrixXd B::Forward_Euler(std::function< double(double) > f, 
                                 std::function< double(double) > gleft, 
                                 std::function< double(double) > gright);

And then, you can call the Forward_Euler method as follows:

    if(fdtype == 'f')
        u = b.Forward_Euler(std::bind(&f,this), 
                            std::bind(&gleft,this), 
                            std::bind(&gright,this));
    ...
    #include <iostream>
    using namespace std;
    void prime_num(int);
    //Desgin: Rafea Fheely
    int main()
    {
    cout << " Enter a number and I will generate the prime numbers up to that number: ";
    int num = 0;
    cin >> num;
    prime_num(num);
    }
    void prime_num( int num)
    {
    bool isPrime=true;
    for ( int i = 0; i <= num; i++)
    {
    for ( int j = 2; j <= num; j++)
    {
    if ( i!=j && i % j == 0 )
    {
    isPrime=false;
    break;
    }
    }
    if (isPrime)
    {
    cout <<"Prime:"<< i << endl;
    }
    isPrime=true;
    }
    }
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.