0
#include <iostream>
using namespace std;

class Model
{
private:
    double a, b;
    double (*fPtr)(double);

public:
    //Constructor
    Model(double lowerLimit, double upperLimit, double (*func)(double))
    {
        a = lowerLimit;
        b = upperLimit;
        fPtr = func;
    }

    // Destructor
    ~Model() {}

    // Member Function Declaration
    double foo1(double x);
    double foo2(int N);

    double Geta() const { return a; }
    double Getb() const { return b; }
};

// Member Function Definition
double Model::foo1(double x)
{
    return x * x - x + 1;
}

double Model::foo2(int N)
{
    double sum = 0.0;
    double h = (b - a) / N;
    for (int i = 1; i < N + 1; i++)
    {
        sum = sum + fPtr(a + (i - 1) * h) + fPtr(a + i * h);
    }
    return sum * h / 2;
}

int main()
{
    Model MyModel(0, 1, foo1);

    double result = Model.foo2(100);
    cout << "result: " << result << endl;
}

I'm trying to define a class in C++ but I keep getting the error

Model MyModel(0,1,foo1): ‘foo1’ was not declared in this scope.

foo1 is a member function of the class, and the value it returns must be passed in to foo2. The *fPtr function pointer must point to foo1.

I'm unable to understand where foo1 needs to be declared.

JeJo
  • 30,635
  • 6
  • 49
  • 88
ask1504
  • 27
  • 3
  • 1
    Look at your definition. It's `Model::foo1`, not `foo1`. But you cannot pass pointer to member function as regular function pointer, these are different types. – Yksisarvinen Oct 14 '22 at 15:41
  • 1
    There are more errors in your program. Post the complete error message that you get. – Jason Oct 14 '22 at 15:41
  • 1
    `Model.foo2(100);` is also a problem, since this code does not have any variable named `Model` – Drew Dormann Oct 14 '22 at 15:41
  • It needs to be declared as a regular function. The shown `foo1`, contrary to what you might believe, is not a function. It is a class method. Even if you correctly refer to it, as `Model::foo1`, the shown code will still fail to compile, but with an even wordier error. – Sam Varshavchik Oct 14 '22 at 15:42
  • Imagine `auto temp = foo1; Model MyModel(0,1,temp);`. Is the error clear now? – 273K Oct 14 '22 at 15:42

1 Answers1

2

Your Model::foo1, is a member function and can not be addressed via free function pointer. You need instead a pointer to member function, which is different from regular function pointer type.

That means you need instead:

class Model
{
    // type alias for pointer to member function (i.e. Model::foo1)
    using MemPtrType = double (Model::*)(double);
private:
    double a, b;
    MemPtrType fPtr;

public:
    // Constructor : use member initializer lists for init members!
    Model(double lowerLimit, double upperLimit, MemPtrType func)
       : a{ lowerLimit }
       , b{ upperLimit }
       , fPtr{ func }
    {}
    // ...
};


The second issue is, how you invoke the pointer to member function. There is a special syntax for this. Read more about it here:

That means you need (alternatively you can use, generic std::invoke (Since C++17) from <functional> header, to invoke the member function pointer with arguments as well).

sum += (this->*fPtr)(a + (i - 1) * h) + (this->*fPtr)(a + i * h);
//     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^^^^^^^^

Also in the main() you need to pass the member function as follows:

Model MyModel{ 0, 1, &Model::foo1 };
//                   ^^^^^^^^^^^^

See a demo in godbolt.org

JeJo
  • 30,635
  • 6
  • 49
  • 88