2013-03-21 11 views
5

Un semplice esempio che spiega come utilizzare std::bind è il seguente:Come si può usare std :: bind?

Si supponga di avere una funzione di 3 argomenti: f3 (x, y, z). Vogliamo avere una funzione di 2 argomenti che è definita come: f2(x,y) = f3(x,5,y). In C++ possiamo facilmente facciamo con std::bind:

auto f2 = std::bind(f3, _1, 5, _2); 

Questo esempio è chiaro: std::bind prende una funzione come primo parametro e poi prende n altri argomenti, dove n è il numero di argomenti della funzione viene considerato come primo argomento per std::bind.

Tuttavia, ho trovato un altro uso di BIND:

void foo(int &x) 
{ 
    ++x; 
} 


int main() 
{ 
    int i = 0; 

    // Binds a copy of i 
    std::bind(foo, i)(); // <------ This is the line that I do not understand. 
    std::cout << i << std::endl; 

} 

E 'chiaro che foo ha un argomento e con std::bind è stato impostato su i. Ma perché usiamo un altro paio di parentesi dopo (foo, i)? E perché non usiamo l'output di std::bind? Voglio dire, perché non abbiamo auto f = std::bind(foo, i)?

+2

Che diavolo è "\\\"? –

+0

Doveva essere un commento: // – Roman

risposta

8

La linea

std::bind(foo, i)(); 

è equivalente a:

auto bar = std::bind(foo, i); 
bar(); 

Esso crea un funtore limite, allora immediatamente chiama (usando la seconda coppia di parentesi).

Edit: Nel nome di accuratezza (e sottolineato dalla @Roman, @daramarak) i due non sono in realtà equivalente a chiamare direttamente la funzione: la i è passato per valore a std :: bind. Il codice equivalente alla chiamata foo direttamente con i, sarebbe:

auto bar = std::bind(foo, std::ref(i)); 
bar(); 
+0

Rimosso i miei commenti su un'obiezione non valida – daramarak

2

tue due domande più o meno rispondere a vicenda. Il trailing () è solo una normale chiamata di funzione. Pertanto, l'espressione significa: "Legatura i a foo, questo produrrà una funzione senza parametri, quindi chiama la funzione risultante." Dal momento che l'autore del codice ha deciso che la funzione non è più necessaria dopo essere stata chiamata, non è memorizzata da nessuna parte.

3

Si lega foo ad un oggetto temporaneo e quindi chiamare immediatamente:

auto f = std::bind(foo, i); 
    f(); 

versione a linea singola:

std::bind(foo, i)(); 
0

Poiché la linea

std::bind(foo, i)() ; 

... fa il stessa cosa di ...

foo(i); 

... questo non è realmente un 'uso' di std :: bind che potresti incontrare nel codice reale, ma serve come una semplice illustrazione di ciò che std :: bind fa, come spiegato in altri risposte.

Come si fa notare, è il solito caso di memorizzare il risultato del vincolo e chiamarlo da qualche altra parte, altrimenti non ha senso complicare il codice con uno std :: bind in primo luogo.

Problemi correlati