web-dev-qa-db-fra.com

c ++ - <type de fonction surchargé non résolu>

Dans ma classe appelée Mat, je veux avoir une fonction qui prend une autre fonction en paramètre. En ce moment, j'ai les 4 fonctions ci-dessous, mais je reçois une erreur lors de l'appel de print (). La deuxième ligne me donne une erreur, mais je ne comprends pas pourquoi, puisque la première fonctionne. La seule différence est que la fonction f n'est pas membre de la classe Mat, mais f2 L'est. L'échec est: error: no matching function for call to Mat::test( < unresolved overloaded function type>, int)'

template <typename F>
int Mat::test(F f, int v){
    return f(v);
}

int Mat::f2(int x){
    return x*x;
}

int f(int x){
    return x*x;
}

void Mat::print(){
    printf("%d\n",test(f ,5));    // works
    printf("%d\n",test(f2 ,5));    // does not work
}

Pourquoi cela arrive-t-il?

28
Mordrag

Le type de pointer-to-member-function Est différent de pointer-to-function.

Le type d'une fonction est différent selon qu'il s'agit d'une fonction ordinaire ou d'une fonction membre non statique d'une classe:

int f(int x);
the type is "int (*)(int)" // since it is an ordinary function

Et

int Mat::f2(int x);
the type is "int (Mat::*)(int)" // since it is a non-static member function of class Mat

Remarque: s'il s'agit d'une fonction membre statique de la classe Fred, son type est le même que s'il s'agissait d'une fonction ordinaire: "int (*)(char,float)"

En C++, les fonctions membres ont un paramètre implicite qui pointe vers l'objet (le pointeur this à l'intérieur de la fonction membre). Les fonctions C normales peuvent être considérées comme ayant une convention d'appel différente des fonctions membres, de sorte que les types de leurs pointeurs (fonction pointeur vers membre par rapport à pointeur vers fonction) sont différents et incompatible. C++ introduit un nouveau type de pointeur, appelé pointeur vers membre, qui ne peut être invoqué qu'en fournissant un objet .

REMARQUE: n'essayez pas de "transtyper" une fonction pointeur en membre en une fonction pointeur en fonction; le résultat est indéfini et probablement désastreux. Par exemple, une fonction pointeur-sur-membre n'est pas requise pour contenir l'adresse machine de la fonction appropriée. Comme cela a été dit dans le dernier exemple, si vous avez un pointeur sur une fonction C normale, utilisez soit une fonction de niveau supérieur (non membre), soit une fonction membre statique (classe).

Plus d'informations à ce sujet ici et ici .

39
user995502

Le problème ici est que f2 est une méthode sur Mat, tandis que f est juste une fonction libre. Vous ne pouvez pas appeler f2 par lui-même, il a besoin d'une instance de Mat pour l'appeler. La façon la plus simple de contourner cela pourrait être:

printf("%d\n", test([=](int v){return this->f2(v);}, 5));

Le = il capturera this, ce que vous devez appeler f2.

5
Barry