yukashima huksay
yukashima huksay

Reputation: 6238

Error calling pointer to member function in C++

I have a large code and I have an error in the middle of it. Here is a simplified version of the parts of the code that has the error.

And this is the error I get:

// Followings are declared in the header

struct Task {
public:
    _COORD p1;
    int p2;
    object p3;
    speed p4;
    bool(Game::*function)(_COORD, int, object, speed);
};


std::vector<Task> tasks;

// Followings are defined in the source

void Game::timer() {
    (some code here)
tasks[i].function(tasks[i].p1, tasks[i].p2, tasks[i].p3, tasks[i].p4);     /*error here*/

expression preceding parentheses of apparent call must have (pointer-to-) function type.

}

void Game::explode(bool(Game::*function)(_COORD, int, object, speed), _COORD p1, int p2, object p3, speed p4) {
    ExplodeTask task;
    task.function = function;
    task.p1 = p1;
    task.p2 = p2;
    task.p3 = p3;
    task.p4 = p4;
    tasks.push_back(task);
}

Does anyone know how to fix it?

Upvotes: 1

Views: 651

Answers (2)

Kadir Erdem Demir
Kadir Erdem Demir

Reputation: 3595

What I advice is usage std::function instead function pointer. Std::function syntax is more friendly any function type can be assigned to it from raw functions to lamdba expression. Also it seems a bit strange too me that you are passing p1,p2,p3,p4 as function parameters even there constant. It will be harder to use that way. At least you could override () operator . And call pass the parameters with () operator once that way user wouldn't need pass parameter second time in "timer" function.

If you must use function pointer I think that is better:

struct Task {
public:
    int p1;
    int p2;
    int p3;
    int p4;
    bool operator()()
    {
        return (functionPtr)(p1,p2,p3,p4);
    }
    bool(*functionPtr)(int, int, int, int );
};

Task t { 1, 2 ,3 ,4, &Game::foo(int, int, int, int) };

Than client can make a easy call without passing parameters like. 
t();

so that client of Task class can call task() directly with ease.

IMHO code will be better like :

#include <vector>
#include <functional>

std::vector<std::function<bool(void)>> functionList;

void taskPusher( std::function<bool(int,int,int,int)> foo , int p1, int p2, int p3, int p4)
{

    std::function<bool()> explodeTask = [=]()
    {
        return foo(p1,p2,p3,p4);
    } ;

    functionList.push_back(explodeTask);
}

void explode()
{
    for ( auto& explodeFoo : functionList)
    {
        explodeFoo();
    }
}

Upvotes: 2

Rabbid76
Rabbid76

Reputation: 210877

The correct syntax, to call a method function pointer is (objectPtr->*methodPtr)() or (object.*methodPtr)():

void Game::timer() {
    int i = 0;
    ...
    (this->*tasks[i].function)(tasks[i].p1, tasks[i].p2, tasks[i].p3, tasks[i].p4);
}

Upvotes: 4

Related Questions