Search code examples
c++classfunction-pointerspointer-to-membermember-functions

Function Pointer inside Class (expression preceding parentheses of apparent call must have (pointer-to-) function type)


I want to use different functions depending on the input to calculate the output. but it says: (expression preceding parentheses of apparent call must have (pointer-to-) function type)

int (TestClass::* Gate_Func)(vector); <<== this is the function I initiated.

and then here: Gate_Func = &TestClass::AND; I can reference to the AND function with Gate_Func

but why output = Gate_Func(InputArr); this one has an error: C++ expression preceding parentheses of apparent call must have (pointer-to-) function type

#include <iostream>
#include <vector>

using namespace std;
class TestClass {
public:
    int AND(vector<int> inputarr) {
        return (inputarr[0] == 1 && inputarr[1] == 1);
    }

    int OR(vector<int> inputarr) {
        return (inputarr[0] == 1 || inputarr[1] == 1);
    }

    int NOT(vector<int> inputarr) {
        if (inputarr[0] != 0) return 0;
        else return 1;
    }

    int (TestClass::* Gate_Func)(vector<int>);

    TestClass(int ChooseFunction, vector<int> inputarr) {
        InputArr = inputarr;
        switch (ChooseFunction)
        {
        case 1:
            Gate_Func = &TestClass::AND;
            break;
        case 2:
            Gate_Func = &TestClass::OR;
            break;
        case 3:
            Gate_Func = &TestClass::NOT;
            break;
        default:
            break;
        }
    }

    void calculation() {
        output = Gate_Func(InputArr); //C++ expression preceding parentheses of apparent call must have (pointer-to-) function type
    }
    vector<int> InputArr;
    int output = 2;
    void printOutput() { cout << output << endl; }
};

int main() {
    vector<int> input = { 1, 1 };

    TestClass obj(1, input);

    obj.printOutput();
}

Oh! I see, thank you guys, so when I use 'this', it's basically like calling the object of the Class and I have to call the function from that object!

Here is the code:

#include <iostream>
#include <vector>

using namespace std;
class TestClass {
public:
    int AND(vector<int> inputarr) {
        return (inputarr[0] == 1 && inputarr[1] == 1);
    }

    int OR(vector<int> inputarr) {
        return (inputarr[0] == 1 || inputarr[1] == 1);
    }

    int NOT(vector<int> inputarr) {
        if (inputarr[0] != 0) return 0;
        else return 1;
    }

    int (TestClass::* Gate_Func)(vector<int>);

    TestClass(int ChooseFunction, vector<int> inputarr) {
        InputArr = inputarr;
        switch (ChooseFunction)
        {
        case 1:
            Gate_Func = &TestClass::AND;
            break;
        case 2:
            Gate_Func = &TestClass::OR;
            break;
        case 3:
            Gate_Func = &TestClass::NOT;
            break;
        default:
            break;
        }
        calculation();
    }

    void calculation() {
        output = (this->*Gate_Func)(InputArr); //C++ expression preceding parentheses of apparent call must have (pointer-to-) function type
    }
    vector<int> InputArr;
    int output = 2;
    void printOutput() { cout << output << endl; }
};

int main() {
    vector<int> input = { 1, 1 };

    TestClass obj(1, input);

    obj.printOutput();
}

Solution

  • The functions AND, OR, and NOT are non-static member functions. They can only be called when an instance of their class is supplied.

    Gate_Func is a pointer to non-static member function. It can point to a non-static member function such as AND, OR, or NOT. In order to invoke it, you must supply an instance of the class (just as you would have to do in order to call AND, OR, or NOT directly). You also need to supply the arguments to the function.

    This is done using a special syntax:

    (p->*Gate_Func)(InputArr);
    

    Here, p is a pointer to the instance on which to invoke the function, and InputArr is the argument. If there are multiple arguments, they are separated by commas just like in an ordinary function call.

    If you can't remember this syntax, you can also do std::invoke(Gate_Func, p, InputArr). (The instance pointer p goes before all the arguments.)

    In your case, I suspect you want to invoke the function on the current instance. You can do this by using this (e.g., (this->*Gate_Func)(InputArr)).