2010-12-14 14 views
7

Ho una lista di MyClass:Che caso è meglio?

struct MyClass { 
    bool is_old_result(int lifetime); 
}; 
std::list<MyClass> results; 
int lifetime = 50; // or something else 

Che caso di rimozione è meglio (C++ design e perfomance):

results.remove_if(
    std::bind2nd(std::mem_fun_ref(&MyClass::is_old_result), lifetime)); 

o

results.remove_if(boost::bind(&MyClass::is_old_result, _1, lifetime)); 

o

struct RemoveFunctor { 
    RemoveFunctor (int lifetime) : lifetime(lifetime) {} 
    bool operator()(const MyClass & m) { return m.is_old_result(lifetime); } 
private: 
    int lifetime; 
}; 
results.remove_if(RemoveFunctor(lifetime)); 

e perché?

P.S. Per favore, nessuna funzione lambda e nessun C++ 0x.

risposta

12

In termini di design, quello che utilizza bind è decisamente il più chiaro. (seguito dall'oggetto funzione esplicita). Perché? Succinta.

In termini di prestazioni, l'oggetto funzione deve essere imbattibile (tutto può essere facilmente analizzato e inline). A seconda di come ottimizza il compilatore, quello che utilizza bind potrebbe corrispondere (la chiamata a is_old_result può essere o meno attraverso un puntatore, a seconda dell'analisi del compilatore).

+0

Sono completamente d'accordo. – ltjax

+0

Concordo anch'io, la sintassi di bind è la più semplice da leggere. Se la prestazione è una preoccupazione secondaria, vai qui. –

+3

Concordo anche e aggiungerò che le prestazioni dovrebbero essere una preoccupazione secondaria a meno che/non abbiate profilato e stabilito che questa affermazione è un collo di bottiglia per le prestazioni. –

3

Con più adatto di denominazione, come ad esempio "IsOldResult" o "ResultOlderThan", direi che la soluzione finale sarebbe il più leggibile, in quanto è quello che la maggior parte passa per la prosa:

results.remove_if(ResultOlderThan(lifetime)); 

Tuttavia, probabilmente andrei solo a scrivere il functor se l'algoritmo che rappresentava si presentava in più contesti. Scrivere una classe di 5 linee che sia fisicamente rimossa dal suo sito di call one-liner singolo sembra eccessivamente dispendioso, per me.

In caso contrario, l'opzione boost :: bind ha il mio voto in quanto ha il minimo di fluff aggiuntivo tra esso e std :: bind2nd (_1 e std :: mem_fun_ref, rispettivamente). Inoltre, boost :: bind funziona per più casi in generale, come nel caso in cui non si vincoli solo una variabile di una funzione che ha solo due parametri.

+0

buon punto sull'adattabile 'ResultOlderThan' –

Problemi correlati