J'ai un gros code et j'ai une erreur au milieu. Voici une version simplifiée des parties du code contenant l'erreur.

Et voici l'erreur que j'obtiens:

// 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*/

l'expression précédant les parenthèses de l'appel apparent doit avoir le type de fonction (pointeur vers).

}

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);
}

Quelqu'un sait-il comment y remédier?

1
yukashima huksay 1 janv. 2016 à 11:33

2 réponses

Meilleure réponse

La syntaxe correcte, pour appeler un pointeur de fonction de méthode est (objectPtr->*methodPtr)() ou (object.*methodPtr)():

void Game::timer() {
    int i = 0;
    ...
    (this->*tasks[i].function)(tasks[i].p1, tasks[i].p2, tasks[i].p3, tasks[i].p4);
}
4
Rabbid76 1 janv. 2016 à 08:53

Ce que je conseille, c'est d'utiliser std :: function à la place du pointeur de fonction. La syntaxe Std :: function est plus conviviale, tout type de fonction peut lui être assigné, des fonctions brutes à l'expression lamdba. De plus, il me semble un peu étrange que vous transmettiez p1, p2, p3, p4 comme paramètres de fonction même là constants. Ce sera plus difficile à utiliser de cette façon. Au moins, vous pouvez remplacer l'opérateur (). Et appelez une fois que vous passez les paramètres avec l'opérateur () de cette façon, l'utilisateur n'aurait pas besoin de passer le paramètre une deuxième fois dans la fonction "timer".

Si vous devez utiliser le pointeur de fonction, je pense que c'est mieux:

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();

Afin que le client de la classe Task puisse appeler task () directement avec facilité.

Le code IMHO sera meilleur comme:

#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();
    }
}
2
Kadir Erdem Demir 1 janv. 2016 à 09:42