2015-05-07 4 views
7

Ho difficoltà a capire la differenza tra i due wrapper funzione std::function e std::mem_fn. Dalla descrizione, mi sembra che std :: function fa tutto ciò che fa std::mem_fn e altro. In quale istanza si dovrebbe usare std::mem_fn su std::function?Qual è la differenza tra std :: function e std :: mem_fn

+2

Significa 'std :: funzione' rispetto al tipo di ritorno di' std :: mem_fn'? Confrontare un modello di classe con un modello di funzione non ha molto senso per me. – chris

risposta

19

Non si può davvero confrontare std::function con std::mem_fn. Il primo è un modello di classe di cui si specifica il tipo, mentre il secondo è un modello di funzione con tipo di ritorno non specificato. Non c'è davvero una situazione in cui in realtà si consideri l'uno contro l'altro.

Un confronto migliore potrebbe essere tra mem_fn e std::bind. Lì, per il caso d'uso specifico di un puntatore-membro, mem_fn sta andando molto meno dettagliato se tutto ciò che si vuole fare è passare tutti gli argomenti. Dato questo tipo semplice:

struct A { 
    int x; 
    int getX() { return x; } 
    int add(int y) { return x+y; } 
}; 

A a{2}; 

Come ti fare un funtore che chiama semplicemente getX() su un dato A?

auto get1 = std::mem_fn(&A::getX); 
auto get2 = std::bind(&A::getX, _1); 

get1(a); // yields 2 
get2(a); // same 

E un argomento aggiuntivo per add?

auto add1 = std::mem_fn(&A::add); 
auto add2 = std::bind(&A::add, _1, _2); 

add1(a, 5); // yields 7 
add2(a, 5); // same 

Così mem_fn è più concisa in questo caso. Tuttavia, se volessimo legare un argomento specifico, ad esempio chiamare add(5) su un dato A, si può fare solo con bind:

auto add_5 = std::bind(&A::add, _1, 5); 
add_5(a); // yields 7 

In definitiva, c'è paragone tra function e mem_fn, ma ci sono momenti di preferire mem_fn a bind.

9

Il wrapper restituito da std::mem_fn è estremamente leggero; è un involucro sottile attorno a un puntatore al membro.

std::function utilizza la cancellazione di tipo, che è molto più pesante.