2012-06-03 45 views
15

Nell'esempio di codice seguente, la chiamata a foo funziona, mentre la chiamata a bar non riesce.Passare una funzione come parametro modello esplicito

Se commento la chiamata a bar, il codice viene compilato, il che indica che la definizione di bar è soddisfacente. Quindi, come sarebbe chiamato correttamente bar?

#include <iostream> 

using namespace std; 

int multiply(int x, int y) 
{ 
    return x * y; 
} 

template <class F> 
void foo(int x, int y, F f) 
{ 
    cout << f(x, y) << endl; 
} 

template <class F> 
void bar(int x, int y) 
{ 
    cout << F(x, y) << endl; 
} 

int main() 
{ 
    foo(3, 4, multiply); // works 
    bar<multiply>(3, 4); // fails 

    return 0; 
} 
+0

Vedere anche [Funzione passata come argomento modello] (https://stackoverflow.com/q/1174169/608639). – jww

risposta

26

Il problema è, multiply non è un tipo ; è un valore ma il modello di funzione bar prevede che l'argomento del modello sia un tipo . Quindi l'errore.

Se si definisce la funzione di modello come:

template <int (*F)(int,int)> //now it'll accept multiply (i.e value) 
void bar(int x, int y) 
{ 
    cout << F(x, y) << endl; 
} 

allora funzionerà. Vedere demo online: http://ideone.com/qJrAe

È possibile semplificare la sintassi con typedef come:

typedef int (*Fun)(int,int); 

template <Fun F> //now it'll accept multiply (i.e value) 
void bar(int x, int y) 
{ 
    cout << F(x, y) << endl; 
} 
+2

Grazie per la chiara spiegazione! – tajmahal

7

multiply non è un tipo, è una funzione. In quel contesto, decade a un puntatore di funzione. Tuttavia, bar è un modello per un tipo che, di nuovo, multiply non lo è.

Nawaz già risposto alla domanda il contrario (come cambiare la definizione di bar per essere utilizzato con le funzioni), ma per rispondere alla tua esplicita domanda di come chiamare bar come lo avete, avete bisogno di un tipo adatto, così:

struct Type { 
    const int result; 
    Type(int x, int y): result(x * y) {} 
    operator int() const { return result; } 
}; 

// usage 
bar<Type>(x, y); 

// (edit) a suitable type doesn't necessarily mean a new type; this works as well 
// if you aren't trying to solve any specific problem 
bar<std::string>(64, 64); 
+0

Se sta per usarlo, allora deve anche cambiare 'bar'. La sintassi 'F (x, y)' dovrebbe diventare 'F (x, y)()'. – Nawaz

+0

@Nawaz No, 'Type' non è in realtà un funtore. È solo un tipo con un costruttore adatto e un sovraccarico dell'output del flusso (in questo caso un operatore di conversione adatto che ha già un sovraccarico dell'output del flusso). (vedi http://ideone.com/AgQGc) –

+0

Ohh .. Ho trascurato che ... forse perché un funtore sarebbe un'alternativa migliore qui, quindi me lo aspettavo. – Nawaz

Problemi correlati