c ++ –

Nella mia class chiamata Mat , voglio avere una funzione che prende un’altra funzione come parametro. In questo momento ho le 4 funzioni di seguito, ma ottengo un errore quando si chiama print (). La seconda riga mi dà un errore, ma non capisco perché, dal momento che il primo funziona. L’unica differenza è che la funzione f non è un membro della class Mat , ma f2 è. L’errore è: error: no matching function for call to Mat::test( , int)'

 template  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 } 

Perché succede?

Il tipo di funzione pointer-to-member-function è diverso da pointer-to-function .

Il tipo di una funzione è diverso a seconda che si tratti di una funzione ordinaria o di una funzione membro non statica di una class:

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

E

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

Nota: se si tratta di una funzione membro statica della class Fred, il suo tipo è lo stesso di una normale funzione: "int (*)(char,float)"

In C ++, le funzioni membro hanno un parametro implicito che punta all’object (il puntatore all’interno della funzione membro). Le normali funzioni C possono essere pensate come aventi una convenzione di chiamata diversa dalle funzioni membro, quindi i tipi dei loro puntatori (da puntatore a membro-funzione vs puntatore-a-funzione) sono diversi e incompatibili. C ++ introduce un nuovo tipo di puntatore, chiamato pointer-to-member, che può essere invocato solo fornendo un object .

NOTA: non tentare di “lanciare” una funzione puntatore-membro-membro in un puntatore-a-funzione; il risultato è indefinito e probabilmente disastroso. Ad esempio, una funzione puntatore-membro non è necessaria per contenere l’indirizzo della macchina della funzione appropriata. Come è stato detto nell’ultimo esempio, se si dispone di un puntatore a una normale funzione C, utilizzare una funzione di livello superiore (non membro) o una funzione membro statica (class).

Maggiori informazioni su questo qui e qui .

Il problema qui è che f2 è un metodo su Mat , mentre f è solo una funzione libera. Non puoi chiamare f2 da solo, ha bisogno di un’istanza di Mat per chiamarlo. Il modo più semplice per aggirare questo potrebbe essere:

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

The = ci catturerà this , che è quello che devi chiamare f2 .