2012-05-21 29 views
6

Ho una funzione che richiede un puntatore a funzione come argomento:C++ funzione bind per l'uso come argomento di un'altra funzione

int func(int a, int (*b)(int, int)) 
{ 
    return b(a,1); 
} 

Ora voglio usare una certa funzione che ha tre argomenti in questa funzione:

int c(int, int, int) 
{ 
    // ... 
} 

Come posso legare il primo argomento di c in modo che io sono in grado di fare:

int i = func(10, c_bound); 

Ho guardato allo std::bind1st ma non riesco a capirlo. Non restituisce un puntatore a funzione giusto? Ho la piena libertà di adattare func in modo che eventuali cambiamenti di approccio siano possibili. Althoug mi piacerebbe che l'utente del mio codice fosse in grado di definire il proprio c ...

notare che quanto sopra è una feroce semplificazione delle funzioni effettive che sto usando.

Il progetto richiede purtroppo C++98.

risposta

12

Non puoi farlo. Dovresti modificare func per eseguire prima un oggetto funzione. Qualcosa di simile:

int func(int a, std::function< int(int, int) > b) 
{ 
    return b(a, rand()); 
} 

In realtà, non v'è alcuna necessità di b essere un std::function, potrebbe essere templato invece:

template< typename T > 
int func(int a, T b) 
{ 
    return b(a, rand()); 
} 

ma vorrei rimanere con la versione std::function per la chiarezza e un po 'meno output del compilatore convoluto su errori.

Poi si sarebbe in grado di fare qualcosa di simile:

int i = func(10, std::bind(&c, _1, _2, some-value)); 

Nota tutto questo è C++ 11, ma è possibile farlo in C++ 03 utilizzando Boost.

+2

anche se Avevo bisogno del codice C++ 98, questa risposta è stata facilmente convertita in equivalente boost. – romeovs

1

Beh, se si sa al momento della compilazione, quello che hai da legare c con, si potrebbe definire una nuova funzione

int c_bound(int a, int b) { 
    return c(a,b,some_value); 
} 

Questo non è ovviamente una soluzione generica, ma potrebbe risolvere i problemi presenti. Altrimenti la soluzione di K-ballo sembra essere l'unica generica facile. Tuttavia, ciò richiede la possibilità di modificare la firma di func. Se hai davvero un'API che non puoi toccare la firma e hai ancora bisogno di legare un argomento E se la soluzione di cui sopra non risolve il tuo caso specifico: (Attenzione, overkill ahead) Ho sempre voluto usare un LLVM soluzione basata per compilare una funzione in fase di esecuzione e passare il suo indirizzo in tali situazioni.

0

Non si può utilizzare una funzione a 3 argomenti come una funzione a 2 argomenti; Principalmente perché non esiste un modo reale per determinare cosa farebbe il terzo parametro.

Mentre la risposta di cui sopra avrebbe funzionato, qui è un'altra opzione:

Se uno dei parametri per c(), in uso all'interno func, è costante, si potrebbe scrivere una funzione wrapper per c(int, int, int):

int d(int a, int b) 
{ 
    return c(a, b, 0); //use a constant parameter 
} 

o, se è possibile determinare il 3 ° parametro dei due determinati parametri, si può anche provare:

int e(int a, int b) 
{ 
    int extra = 0; 
    ///Determine extra from a, and b 
    return c(a, b, c); 
} 
Problemi correlati